From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 79180 invoked by alias); 4 Jun 2018 17:05:25 -0000 Mailing-List: contact elfutils-devel-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Post: List-Help: List-Subscribe: Sender: elfutils-devel-owner@sourceware.org Received: (qmail 77141 invoked by uid 89); 4 Jun 2018 17:05:25 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Checked: by ClamAV 0.99.4 on sourceware.org X-Virus-Found: No X-Spam-SWARE-Status: No, score=-26.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 spammy= X-Spam-Status: No, score=-26.9 required=5.0 tests=BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,RCVD_IN_DNSWL_NONE,SPF_PASS autolearn=ham version=3.3.2 X-Spam-Checker-Version: SpamAssassin 3.3.2 (2011-06-06) on sourceware.org X-Spam-Level: X-HELO: gnu.wildebeest.org Received: from wildebeest.demon.nl (HELO gnu.wildebeest.org) (212.238.236.112) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with ESMTP; Mon, 04 Jun 2018 17:05:22 +0000 Received: from tarox.wildebeest.org (tarox.wildebeest.org [172.31.17.39]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id 508D0307C549; Mon, 4 Jun 2018 19:05:19 +0200 (CEST) Received: by tarox.wildebeest.org (Postfix, from userid 1000) id 40B09418ABBF; Mon, 4 Jun 2018 19:05:19 +0200 (CEST) From: Mark Wielaard To: elfutils-devel@sourceware.org Cc: Mark Wielaard Subject: [PATCH] readelf: Don't allocate string with asprintf, but reuse buffer with sprintf. Date: Mon, 04 Jun 2018 17:05:00 -0000 Message-Id: <1528131916-16956-1-git-send-email-mark@klomp.org> X-Mailer: git-send-email 1.8.3.1 X-Spam-Flag: NO X-IsSubscribed: yes X-SW-Source: 2018-q2/txt/msg00147.txt.bz2 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 --- 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 + * 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 + * 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