This is the mail archive of the 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]

Commit: Speed-ups for objdump

Hi Guys,

  I am applying a couple of patches to the mainline to speed up the
  performance of objdump when it is mixing disassembly with source code
  and line number output.

  The first patch is quite straightforward, it just adds some early
  exits to the lookup_address_in_function_table() function for when we
  know that the search will fail.

  The second patch might be a bit more controversial - it makes objdump
  call bfd_close_all_done on the last bfd that it opens, instead of
  calling bfd_close.  This has the advantage that it does not call the
  _close_and_cleanup functions attached to the bfd, which can save a lot
  of time.  (We are talking 2-3 minutes on a fast x86_64 box for a large
  executable with a lot of debug information).

  The bfd_close_all_done function does not release malloc'ed memory, but
  this will not matter as objdump is about to exit anyway and so the OS
  will reclaim everything for us.  This might make some memory checkers
  complain, but I think that the speed gains are worth it.

2017-01-09  Nick Clifton  <>

	* dwarf2.c (lookup_address_in_function_table): Return early if
	there are no functions in the given comp unit, or if the high
	address of the last function in the comp unit is less than the
	desired address.

2017-01-09  Nick Clifton  <>

	* objdump.c (display_file): Add new parameter 'last_file'.  If
	last_file is true, do not call bfd_close at the end of the
	(main): Set the value of the last_file parameter when calling

diff --git a/bfd/dwarf2.c b/bfd/dwarf2.c
index b477d27..40edd91 100644
--- a/bfd/dwarf2.c
+++ b/bfd/dwarf2.c
@@ -2336,9 +2336,15 @@ lookup_address_in_function_table (struct comp_unit *unit,
   bfd_size_type low, high, mid, first;
   struct arange *arange;
+  if (number_of_functions == 0)
+    return FALSE;
   if (!build_lookup_funcinfo_table (unit))
     return FALSE;
+  if (unit->lookup_funcinfo_table[number_of_functions - 1].high_addr < addr)
+    return FALSE;
   /* Find the first function in the lookup table which may contain the
      specified address.  */
   low = 0;
diff --git a/binutils/objdump.c b/binutils/objdump.c
index f61968b..c03dfc5 100644
--- a/binutils/objdump.c
+++ b/binutils/objdump.c
@@ -3616,7 +3616,7 @@ display_any_bfd (bfd *file, int level)
 static void
-display_file (char *filename, char *target)
+display_file (char *filename, char *target, bfd_boolean last_file)
   bfd *file;
@@ -3635,7 +3635,18 @@ display_file (char *filename, char *target)
   display_any_bfd (file, 0);
-  bfd_close (file);
+  /* This is an optimization to improve the speed of objdump, especially when
+     dumping a file with lots of associated debug informatiom.  Calling
+     bfd_close on such a file can take a non-trivial amount of time as there
+     are lots of lists to walk and buffers to free.  This is only really
+     necessary however if we are about to load another file and we need the
+     memory back.  Otherwise, if we are about to exit, then we can save (a lot
+     of) time by only doing a quick close, and allowing the OS to reclaim the
+     memory for us.  */
+  if (! last_file)
+    bfd_close (file);
+  else
+    bfd_close_all_done (file);
@@ -3913,10 +3924,13 @@ main (int argc, char **argv)
       if (optind == argc)
-	display_file ("a.out", target);
+	display_file ("a.out", target, TRUE);
 	for (; optind < argc;)
-	  display_file (argv[optind++], target);
+	  {
+	    display_file (argv[optind], target, optind == argc - 1);
+	    optind++;
+	  }
   free_only_list ();

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