This is the mail archive of the elfutils-devel@sourceware.org mailing list for the elfutils 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]

[PATCH] readelf: Don't allocate string with asprintf, but reuse buffer with sprintf.


Since we are single threaded we can just use a static result buffer for
format_dwarf_addr as long as we make sure to print the result before
calling format_dwarf_addr again. This removes lots of malloc/free calls.

On my machine eu-readelf -N --debug-dump=info libxul.so
goes from 57 seconds to 55 seconds.

Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 src/ChangeLog |  20 +++++++
 src/readelf.c | 182 ++++++++++++++++++++++++----------------------------------
 2 files changed, 96 insertions(+), 106 deletions(-)

diff --git a/src/ChangeLog b/src/ChangeLog
index 9ee9650..37e2471 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,5 +1,25 @@
 2018-06-04  Mark Wielaard  <mark@klomp.org>
 
+	* readelf (format_result): New static char pointer.
+	(format_result_size): New static size_t.
+	(format_dwarf_addr): Calculate max string size, reuse format_result
+	if possible, otherwise realloc. Use sprintf on result, not asprintf.
+	(print_ops): Don't free format_dwarf_addr, make sure result is
+	printed before calling format_dwarf_addr again.
+	(print_debug_addr_section): Likewise.
+	(print_debug_aranges_section): Likewise.
+	(print_debug_rnglists_section): Likewise.
+	(print_debug_ranges_section): Likewise.
+	(print_debug_frame_section): Likewise.
+	(attr_callback): Likewise.
+	(print_decoded_line_section): Likewise.
+	(print_debug_line_section): Likewise.
+	(print_debug_loclists_section): Likewise.
+	(print_debug_loc_section): Likewise.
+	(print_gdb_index_section): Likewsie.
+
+2018-06-04  Mark Wielaard  <mark@klomp.org>
+
 	* readelf.c (yes_str): New static char pointer.
 	(no_str): Likewise.
 	(main): Set yes_str and no_str using gettext.
diff --git a/src/readelf.c b/src/readelf.c
index 81d1094..8f37f17 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -3695,6 +3695,9 @@ print_attributes (Ebl *ebl, const GElf_Ehdr *ehdr)
 }
 
 
+static char *format_result = NULL;
+static size_t format_result_size = 0;
+
 static char *
 format_dwarf_addr (Dwfl_Module *dwflmod,
 		   int address_size, Dwarf_Addr address, Dwarf_Addr raw)
@@ -3724,56 +3727,71 @@ format_dwarf_addr (Dwfl_Module *dwflmod,
     }
 
   char *result;
+  size_t max_size = ((name != NULL ? strlen (name) : 0)
+		     + (scn != NULL ? strlen (scn) : 0)
+		     + (2 + 8 * 2) * 2 + 6);
+  if (max_size > format_result_size)
+    {
+      max_size *= 2; /* A bit more, so we don't immediately realloc again.  */
+      result = realloc (format_result, max_size);
+      if (result == NULL)
+	error (EXIT_FAILURE, 0, _("memory exhausted"));
+      format_result_size = max_size;
+      format_result = result;
+    }
+  else
+    result = format_result;
+
   if ((name != NULL
        ? (off != 0
 	  ? (scn != NULL
 	     ? (address_size == 0
-		? asprintf (&result,
-			    gettext ("%s+%#" PRIx64 " <%s+%#" PRIx64 ">"),
-			    scn, address, name, off)
-		: asprintf (&result,
-			    gettext ("%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
-			    scn, 2 + address_size * 2, address,
-			    name, off))
+		? sprintf (result,
+			   "%s+%#" PRIx64 " <%s+%#" PRIx64 ">",
+			   scn, address, name, off)
+		: sprintf (result,
+			   "%s+%#0*" PRIx64 " <%s+%#" PRIx64 ">",
+			   scn, 2 + address_size * 2, address,
+			   name, off))
 	     : (address_size == 0
-		? asprintf (&result,
-			    gettext ("%#" PRIx64 " <%s+%#" PRIx64 ">"),
-			    address, name, off)
-		: asprintf (&result,
-			    gettext ("%#0*" PRIx64 " <%s+%#" PRIx64 ">"),
-			    2 + address_size * 2, address,
-			    name, off)))
+		? sprintf (result,
+			   "%#" PRIx64 " <%s+%#" PRIx64 ">",
+			   address, name, off)
+		: sprintf (result,
+			   "%#0*" PRIx64 " <%s+%#" PRIx64 ">",
+			   2 + address_size * 2, address,
+			   name, off)))
 	  : (scn != NULL
 	     ? (address_size == 0
-		? asprintf (&result,
-			    gettext ("%s+%#" PRIx64 " <%s>"),
-			    scn, address, name)
-		: asprintf (&result,
-			    gettext ("%s+%#0*" PRIx64 " <%s>"),
-			    scn, 2 + address_size * 2, address, name))
+		? sprintf (result,
+			   "%s+%#" PRIx64 " <%s>",
+			   scn, address, name)
+		: sprintf (result,
+			   "%s+%#0*" PRIx64 " <%s>",
+			   scn, 2 + address_size * 2, address, name))
 	     : (address_size == 0
-		? asprintf (&result,
-			    gettext ("%#" PRIx64 " <%s>"),
-			    address, name)
-		: asprintf (&result,
-			    gettext ("%#0*" PRIx64 " <%s>"),
-			    2 + address_size * 2, address, name))))
+		? sprintf (result,
+			   "%#" PRIx64 " <%s>",
+			   address, name)
+		: sprintf (result,
+			   "%#0*" PRIx64 " <%s>",
+			   2 + address_size * 2, address, name))))
        : (scn != NULL
 	  ? (address_size == 0
-	     ? asprintf (&result,
-			 gettext ("%s+%#" PRIx64),
-			 scn, address)
-	     : asprintf (&result,
-			 gettext ("%s+%#0*" PRIx64),
-			 scn, 2 + address_size * 2, address))
+	     ? sprintf (result,
+			"%s+%#" PRIx64,
+			scn, address)
+	     : sprintf (result,
+			"%s+%#0*" PRIx64,
+			scn, 2 + address_size * 2, address))
 	  : (address_size == 0
-	     ? asprintf (&result,
-			 "%#" PRIx64,
-			 address)
-	     : asprintf (&result,
-			 "%#0*" PRIx64,
-			 2 + address_size * 2, address)))) < 0)
-    error (EXIT_FAILURE, 0, _("memory exhausted"));
+	     ? sprintf (result,
+			"%#" PRIx64,
+			address)
+	     : sprintf (result,
+			"%#0*" PRIx64,
+			2 + address_size * 2, address)))) < 0)
+    error (EXIT_FAILURE, 0, _("sprintf failure"));
 
   return result;
 }
@@ -4355,7 +4373,6 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
 	  char *a = format_dwarf_addr (dwflmod, 0, addr, addr);
 	  printf ("%*s[%2" PRIuMAX "] %s %s\n",
 		  indent, "", (uintmax_t) offset, op_name, a);
-	  free (a);
 
 	  offset += 1 + addrsize;
 	  break;
@@ -4501,7 +4518,6 @@ print_ops (Dwfl_Module *dwflmod, Dwarf *dbg, int indent, int indentrest,
 	    {
 	      a = format_dwarf_addr (dwflmod, 0, addr, addr);
 	      printf ("%s\n", a);
-	      free (a);
 	    }
 	  break;
 
@@ -5287,7 +5303,6 @@ print_debug_addr_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
 	  char *a = format_dwarf_addr (dwflmod, address_size,
 				       addr, addr);
 	  printf ("%s\n", a);
-	  free (a);
 	}
       printf ("\n");
 
@@ -5505,16 +5520,14 @@ print_debug_aranges_section (Dwfl_Module *dwflmod __attribute__ ((unused)),
 
 	  char *b = format_dwarf_addr (dwflmod, address_size, range_address,
 				       range_address);
+	  printf ("   %s", b);
 	  char *e = format_dwarf_addr (dwflmod, address_size,
 				       range_address + range_length - 1,
 				       range_length);
 	  if (segment_size != 0)
-	    printf (gettext ("   %s..%s (%" PRIx64 ")\n"), b, e,
-		    (uint64_t) segment);
+	    printf ("..%s (%" PRIx64 ")\n", e, (uint64_t) segment);
 	  else
-	    printf (gettext ("   %s..%s\n"), b, e);
-	  free (b);
-	  free (e);
+	    printf ("..%s\n", e);
 	}
 
     next_table:
@@ -5664,7 +5677,6 @@ print_debug_rnglists_section (Dwfl_Module *dwflmod,
 	  else
 	    printf (gettext (" CU [%6" PRIx64 "] base: %s\n"),
 		    dwarf_dieoffset (&cudie), basestr);
-	  free (basestr);
 	}
       else
 	printf (gettext (" Not associated with a CU.\n"));
@@ -5750,7 +5762,6 @@ print_debug_rnglists_section (Dwfl_Module *dwflmod,
 		      a1 = format_dwarf_addr (dwflmod, address_size,
 					      addr, addr);
 		      printf ("      %s\n", a1);
-		      free (a1);
 		    }
 		}
 	      break;
@@ -5777,12 +5788,10 @@ print_debug_rnglists_section (Dwfl_Module *dwflmod,
 		    {
 		      a1 = format_dwarf_addr (dwflmod, address_size,
 					      addr1, addr1);
+		      printf ("      %s..\n", a1);
 		      a2 = format_dwarf_addr (dwflmod, address_size,
 					      addr2 - 1, addr2);
-		      printf ("      %s..\n", a1);
 		      printf ("      %s\n", a2);
-		      free (a1);
-		      free (a2);
 		    }
 		}
 	      break;
@@ -5809,12 +5818,10 @@ print_debug_rnglists_section (Dwfl_Module *dwflmod,
 		      addr2 = addr1 + op2;
 		      a1 = format_dwarf_addr (dwflmod, address_size,
 					      addr1, addr1);
+		      printf ("      %s..\n", a1);
 		      a2 = format_dwarf_addr (dwflmod, address_size,
 					      addr2 - 1, addr2);
-		      printf ("      %s..\n", a1);
 		      printf ("      %s..\n", a2);
-		      free (a1);
-		      free (a2);
 		    }
 		}
 	      break;
@@ -5832,12 +5839,10 @@ print_debug_rnglists_section (Dwfl_Module *dwflmod,
 		  op1 += base;
 		  op2 += base;
 		  a1 = format_dwarf_addr (dwflmod, address_size, op1, op1);
+		  printf ("      %s..\n", a1);
 		  a2 = format_dwarf_addr (dwflmod, address_size,
 					  op2 - 1, op2);
-		  printf ("      %s..\n", a1);
 		  printf ("      %s\n", a2);
-		  free (a1);
-		  free (a2);
 		}
 	      break;
 
@@ -5860,7 +5865,6 @@ print_debug_rnglists_section (Dwfl_Module *dwflmod,
 		{
 		  a1 = format_dwarf_addr (dwflmod, address_size, base, base);
 		  printf ("      %s\n", a1);
-		  free (a1);
 		}
 	      break;
 
@@ -5883,12 +5887,10 @@ print_debug_rnglists_section (Dwfl_Module *dwflmod,
 	      if (! print_unresolved_addresses)
 		{
 		  a1 = format_dwarf_addr (dwflmod, address_size, op1, op1);
+		  printf ("      %s..\n", a1);
 		  a2 = format_dwarf_addr (dwflmod, address_size,
 					  op2 - 1, op2);
-		  printf ("      %s..\n", a1);
 		  printf ("      %s\n", a2);
-		  free (a1);
-		  free (a2);
 		}
 	      break;
 
@@ -5912,13 +5914,12 @@ print_debug_rnglists_section (Dwfl_Module *dwflmod,
 	      if (! print_unresolved_addresses)
 		{
 		  a1 = format_dwarf_addr (dwflmod, address_size, op1, op1);
+		  printf ("      %s..\n", a1);
+
 		  op2 = op1 + op2;
 		  a2 = format_dwarf_addr (dwflmod, address_size,
 					  op2 - 1, op2);
-		  printf ("      %s..\n", a1);
 		  printf ("      %s\n", a2);
-		  free (a1);
-		  free (a2);
 		}
 	      break;
 
@@ -5990,7 +5991,6 @@ print_debug_ranges_section (Dwfl_Module *dwflmod,
 	  else
 	    printf (gettext ("\n CU [%6" PRIx64 "] base: %s\n"),
 		    dwarf_dieoffset (&cudie), basestr);
-	  free (basestr);
 	}
       last_cu = cu;
 
@@ -6019,7 +6019,6 @@ print_debug_ranges_section (Dwfl_Module *dwflmod,
 	{
 	  char *b = format_dwarf_addr (dwflmod, address_size, end, end);
 	  printf (gettext (" [%6tx] base address\n          %s\n"), offset, b);
-	  free (b);
 	  base = end;
 	}
       else if (begin == 0 && end == 0) /* End of list entry.  */
@@ -6041,12 +6040,10 @@ print_debug_ranges_section (Dwfl_Module *dwflmod,
 	    {
 	      char *b = format_dwarf_addr (dwflmod, address_size, base + begin,
 					   base + begin);
+	      printf ("          %s..\n", b);
 	      char *e = format_dwarf_addr (dwflmod, address_size,
 					   base + end - 1, base + end);
-	      printf ("          %s..\n", b);
 	      printf ("          %s\n", e);
-	      free (b);
-	      free (e);
 	    }
 
 	  first = false;
@@ -6818,7 +6815,6 @@ print_debug_frame_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
 		  "   initial_location:         %s",
 		  offset, (uint64_t) unit_length,
 		  cie->cie_offset, (uint64_t) cie_id, a);
-	  free (a);
 	  if ((fde_encoding & 0x70) == DW_EH_PE_pcrel)
 	    {
 	      vma_base = (((uint64_t) shdr->sh_offset
@@ -6986,7 +6982,6 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
 	    printf ("           %*s%-20s (%s) %s\n",
 		    (int) (level * 2), "", dwarf_attr_name (attr),
 		    dwarf_form_name (form), a);
-	  free (a);
 	}
       break;
 
@@ -7331,7 +7326,6 @@ attr_callback (Dwarf_Attribute *attrp, void *arg)
 	  printf ("           %*s%-20s (%s) %" PRIuMAX " (%s)\n",
 		  (int) (level * 2), "", dwarf_attr_name (attr),
 		  dwarf_form_name (form), (uintmax_t) num, a);
-	  free (a);
 	}
       else
 	{
@@ -7843,7 +7837,6 @@ print_decoded_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
 		  (epilogue_begin ? 'E' : ' '),
 		  (endseq ? '*' : ' '),
 		  disc, isa, lineop, a);
-	  free (a);
 
 	  if (endseq)
 	    printf("\n");
@@ -8535,7 +8528,6 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
 		printf (gettext ("\
  special opcode %u: address+%u = %s, line%+d = %zu\n"),
 			opcode, op_addr_advance, a, line_increment, line);
-	      free (a);
 	    }
 	  else if (opcode == 0)
 	    {
@@ -8577,7 +8569,6 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
 		  {
 		    char *a = format_dwarf_addr (dwflmod, 0, address, address);
 		    printf (gettext (" set address to %s\n"), a);
-		    free (a);
 		  }
 		  break;
 
@@ -8650,7 +8641,6 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
 		    else
 		      printf (gettext (" advance address by %u to %s\n"),
 			      op_addr_advance, a);
-		    free (a);
 		  }
 		  break;
 
@@ -8710,7 +8700,6 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
 		      printf (gettext ("\
  advance address by constant %u to %s\n"),
 			      op_addr_advance, a);
-		    free (a);
 		  }
 		  break;
 
@@ -8728,7 +8717,6 @@ print_debug_line_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
 		    printf (gettext ("\
  advance address by fixed value %u to %s\n"),
 			    u128, a);
-		    free (a);
 		  }
 		  break;
 
@@ -8895,7 +8883,6 @@ print_debug_loclists_section (Dwfl_Module *dwflmod,
 	  else
 	    printf (gettext (" CU [%6" PRIx64 "] base: %s\n"),
 		    dwarf_dieoffset (&cudie), basestr);
-	  free (basestr);
 	}
       else
 	printf (gettext (" Not associated with a CU.\n"));
@@ -8981,7 +8968,6 @@ print_debug_loclists_section (Dwfl_Module *dwflmod,
 		      a1 = format_dwarf_addr (dwflmod, address_size,
 					      addr, addr);
 		      printf ("      %s\n", a1);
-		      free (a1);
 		    }
 		}
 	      break;
@@ -9008,12 +8994,10 @@ print_debug_loclists_section (Dwfl_Module *dwflmod,
 		    {
 		      a1 = format_dwarf_addr (dwflmod, address_size,
 					      addr1, addr1);
+		      printf ("      %s..\n", a1);
 		      a2 = format_dwarf_addr (dwflmod, address_size,
 					      addr2 - 1, addr2);
-		      printf ("      %s..\n", a1);
 		      printf ("      %s\n", a2);
-		      free (a1);
-		      free (a2);
 		    }
 		}
 	      if ((uint64_t) (nexthdr - readp) < 1)
@@ -9048,12 +9032,10 @@ print_debug_loclists_section (Dwfl_Module *dwflmod,
 		      addr2 = addr1 + op2;
 		      a1 = format_dwarf_addr (dwflmod, address_size,
 					      addr1, addr1);
+		      printf ("      %s..\n", a1);
 		      a2 = format_dwarf_addr (dwflmod, address_size,
 					      addr2 - 1, addr2);
-		      printf ("      %s..\n", a1);
 		      printf ("      %s..\n", a2);
-		      free (a1);
-		      free (a2);
 		    }
 		}
 	      if ((uint64_t) (nexthdr - readp) < 1)
@@ -9079,12 +9061,10 @@ print_debug_loclists_section (Dwfl_Module *dwflmod,
 		  op1 += base;
 		  op2 += base;
 		  a1 = format_dwarf_addr (dwflmod, address_size, op1, op1);
+		  printf ("      %s..\n", a1);
 		  a2 = format_dwarf_addr (dwflmod, address_size,
 					  op2 - 1, op2);
-		  printf ("      %s..\n", a1);
 		  printf ("      %s\n", a2);
-		  free (a1);
-		  free (a2);
 		}
 	      if ((uint64_t) (nexthdr - readp) < 1)
 		goto invalid_entry;
@@ -9126,7 +9106,6 @@ print_debug_loclists_section (Dwfl_Module *dwflmod,
 		{
 		  a1 = format_dwarf_addr (dwflmod, address_size, base, base);
 		  printf ("      %s\n", a1);
-		  free (a1);
 		}
 	      break;
 
@@ -9149,12 +9128,10 @@ print_debug_loclists_section (Dwfl_Module *dwflmod,
 	      if (! print_unresolved_addresses)
 		{
 		  a1 = format_dwarf_addr (dwflmod, address_size, op1, op1);
+		  printf ("      %s..\n", a1);
 		  a2 = format_dwarf_addr (dwflmod, address_size,
 					  op2 - 1, op2);
-		  printf ("      %s..\n", a1);
 		  printf ("      %s\n", a2);
-		  free (a1);
-		  free (a2);
 		}
 	      if ((uint64_t) (nexthdr - readp) < 1)
 		goto invalid_entry;
@@ -9186,13 +9163,12 @@ print_debug_loclists_section (Dwfl_Module *dwflmod,
 	      if (! print_unresolved_addresses)
 		{
 		  a1 = format_dwarf_addr (dwflmod, address_size, op1, op1);
+		  printf ("      %s..\n", a1);
+
 		  op2 = op1 + op2;
 		  a2 = format_dwarf_addr (dwflmod, address_size,
 					  op2 - 1, op2);
-		  printf ("      %s..\n", a1);
 		  printf ("      %s\n", a2);
-		  free (a1);
-		  free (a2);
 		}
 	      if ((uint64_t) (nexthdr - readp) < 1)
 		goto invalid_entry;
@@ -9274,7 +9250,6 @@ print_debug_loc_section (Dwfl_Module *dwflmod,
 	else
 	  printf (gettext ("\n CU [%6" PRIx64 "] base: %s\n"),
 		  dwarf_dieoffset (&cudie), basestr);
-	free (basestr);
        }
       last_cu = cu;
 
@@ -9403,7 +9378,6 @@ print_debug_loc_section (Dwfl_Module *dwflmod,
 	{
 	  char *b = format_dwarf_addr (dwflmod, address_size, end, end);
 	  printf (gettext (" [%6tx] base address\n          %s\n"), offset, b);
-	  free (b);
 	  base = end;
 	}
       else if (begin == 0 && end == 0) /* End of list entry.  */
@@ -9429,12 +9403,10 @@ print_debug_loc_section (Dwfl_Module *dwflmod,
 	      Dwarf_Addr dae = use_base ? base + end : end;
 	      char *b = format_dwarf_addr (dwflmod, address_size,
 					   dab, dab);
+	      printf ("          %s..\n", b);
 	      char *e = format_dwarf_addr (dwflmod, address_size,
 					   dae - 1, dae);
-	      printf ("          %s..\n", b);
 	      printf ("          %s\n", e);
-	      free (b);
-	      free (e);
 	    }
 
 	  if (endp - readp <= (ptrdiff_t) len)
@@ -10694,11 +10666,9 @@ print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
       readp += 4;
 
       char *l = format_dwarf_addr (dwflmod, 8, low, low);
+      printf (" [%4zu] %s..", n, l);
       char *h = format_dwarf_addr (dwflmod, 8, high - 1, high);
-      printf (" [%4zu] %s..%s, CU index: %5" PRId32 "\n",
-	      n, l, h, idx);
-      free (l);
-      free (h);
+      printf ("%s, CU index: %5" PRId32 "\n", h, idx);
       n++;
     }
 
-- 
1.8.3.1


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