[PATCH] readelf: Don't allocate string with asprintf, but reuse buffer with sprintf.
Mark Wielaard
mark@klomp.org
Mon Jun 4 17:05:00 GMT 2018
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
More information about the Elfutils-devel
mailing list