[PATCH] libdw and libdwfl srcfiles and srclines fixes for partial_units.
by Mark Wielaard
dwfl_getsrclines would always fail, even when lines were found.
dwarf_decl_file, and other functions relying on srcfiles or srclines would
fail for DIEs in partial_units because stmt_lists on partial_units
were ignored.
Note that dwz contained a bug which makes things fail in __libdw_formptr
for DW_AT_stmt_list with a bogus DW_FORM even with these fixes.
https://bugzilla.redhat.com/show_bug.cgi?id=919755
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
libdw/ChangeLog | 5 ++
libdw/dwarf_getsrcfiles.c | 5 +-
libdw/dwarf_getsrclines.c | 5 +-
libdwfl/ChangeLog | 4 ++
libdwfl/dwfl_getsrclines.c | 4 +-
tests/ChangeLog | 8 +++
tests/Makefile.am | 8 ++-
tests/dwfllines.c | 164 +++++++++++++++++++++++++++++++++++++++++++++
tests/run-dwfllines.sh | 88 ++++++++++++++++++++++++
9 files changed, 282 insertions(+), 9 deletions(-)
create mode 100644 tests/dwfllines.c
create mode 100755 tests/run-dwfllines.sh
diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 2900ef6..16acf5c 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,8 @@
+2013-03-12 Mark Wielaard <mjw(a)redhat.com>
+
+ * dwarf_getsrcfiles.c (dwarf_getsrcfiles): Allow DW_TAG_partial_unit.
+ * dwarf_getsrclines.c (dwarf_getsrclines): Likewise.
+
2013-02-15 Mark Wielaard <mjw(a)redhat.com>
* dwarf_formstring.c (dwarf_formstring): Check dbg_ret->sectiondata,
diff --git a/libdw/dwarf_getsrcfiles.c b/libdw/dwarf_getsrcfiles.c
index d026820..4bfc34b 100644
--- a/libdw/dwarf_getsrcfiles.c
+++ b/libdw/dwarf_getsrcfiles.c
@@ -1,5 +1,5 @@
/* Return source file information of CU.
- Copyright (C) 2004, 2005 Red Hat, Inc.
+ Copyright (C) 2004, 2005, 2013 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <drepper(a)redhat.com>, 2004.
@@ -40,7 +40,8 @@ int
dwarf_getsrcfiles (Dwarf_Die *cudie, Dwarf_Files **files, size_t *nfiles)
{
if (unlikely (cudie == NULL
- || INTUSE(dwarf_tag) (cudie) != DW_TAG_compile_unit))
+ || (INTUSE(dwarf_tag) (cudie) != DW_TAG_compile_unit
+ && INTUSE(dwarf_tag) (cudie) != DW_TAG_partial_unit)))
return -1;
int res = -1;
diff --git a/libdw/dwarf_getsrclines.c b/libdw/dwarf_getsrclines.c
index 0758023..c24aebb 100644
--- a/libdw/dwarf_getsrclines.c
+++ b/libdw/dwarf_getsrclines.c
@@ -1,5 +1,5 @@
/* Return line number information of CU.
- Copyright (C) 2004-2010 Red Hat, Inc.
+ Copyright (C) 2004-2010, 2013 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <drepper(a)redhat.com>, 2004.
@@ -69,7 +69,8 @@ int
dwarf_getsrclines (Dwarf_Die *cudie, Dwarf_Lines **lines, size_t *nlines)
{
if (unlikely (cudie == NULL
- || INTUSE(dwarf_tag) (cudie) != DW_TAG_compile_unit))
+ || (INTUSE(dwarf_tag) (cudie) != DW_TAG_compile_unit
+ && INTUSE(dwarf_tag) (cudie) != DW_TAG_partial_unit)))
return -1;
int res = -1;
diff --git a/libdwfl/ChangeLog b/libdwfl/ChangeLog
index 78139ba..15a6c9c 100644
--- a/libdwfl/ChangeLog
+++ b/libdwfl/ChangeLog
@@ -1,3 +1,7 @@
+2013-03-12 Mark Wielaard <mjw(a)redhat.com>
+
+ * dwfl_getsrclines.c (dwfl_getsrclines): Return 0 on success.
+
2013-02-22 Mark Wielaard <mjw(a)redhat.com>
* open.c (__libdw_gunzip,__libdw_bunzip2,__libdw_unlzma): Define
diff --git a/libdwfl/dwfl_getsrclines.c b/libdwfl/dwfl_getsrclines.c
index cc8cb7c..bdfcf5c 100644
--- a/libdwfl/dwfl_getsrclines.c
+++ b/libdwfl/dwfl_getsrclines.c
@@ -1,5 +1,5 @@
/* Fetch source line information for CU.
- Copyright (C) 2005 Red Hat, Inc.
+ Copyright (C) 2005, 2013 Red Hat, Inc.
This file is part of elfutils.
This file is free software; you can redistribute it and/or modify
@@ -44,5 +44,5 @@ dwfl_getsrclines (Dwarf_Die *cudie, size_t *nlines)
}
*nlines = cu->die.cu->lines->nlines;
- return -1;
+ return 0;
}
diff --git a/tests/ChangeLog b/tests/ChangeLog
index d181cd5..ca06a55 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,11 @@
+2013-03-12 Mark Wielaard <mjw(a)redhat.com>
+
+ * run-dwfllines.sh: New test.
+ * dwfllines.c: New test program.
+ * Makefile.am (TESTS): Add run-dwfllines.sh.
+ (EXTRA_DIST): Likewise.
+ (dwfllines_LDADD): New variable.
+
2013-02-22 Mark Wielaard <mjw(a)redhat.com>
* Makefile.am (TESTS): Remove run-readelf-s.sh and run-dwflsyms.sh.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index 63184f8..a5f7a8c 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -51,7 +51,7 @@ check_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \
dwfl-bug-getmodules dwarf-getmacros addrcfi \
test-flag-nobits dwarf-getstring rerequest_tag \
alldts md5-sha1-test typeiter low_high_pc \
- test-elf_cntl_gelf_getshdr dwflsyms
+ test-elf_cntl_gelf_getshdr dwflsyms dwfllines
asm_TESTS = asm-tst1 asm-tst2 asm-tst3 asm-tst4 asm-tst5 \
asm-tst6 asm-tst7 asm-tst8 asm-tst9
@@ -85,7 +85,7 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \
run-readelf-d.sh run-readelf-gdb_index.sh run-unstrip-n.sh \
run-low_high_pc.sh run-macro-test.sh run-elf_cntl_gelf_getshdr.sh \
run-test-archive64.sh run-readelf-vmcoreinfo.sh \
- run-readelf-mixed-corenote.sh
+ run-readelf-mixed-corenote.sh run-dwfllines.sh
if !STANDALONE
check_PROGRAMS += msg_tst md5-sha1-test
@@ -192,7 +192,8 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
run-readelf-mixed-corenote.sh testfile63.bz2 testfile64.bz2 \
testfile65.bz2 testfile67.bz2 testfile68.bz2 \
testfile69.core.bz2 testfile69.so.bz2 \
- testfile70.core.bz2 testfile70.exec.bz2
+ testfile70.core.bz2 testfile70.exec.bz2 \
+ run-dwfllines.sh
if USE_VALGRIND
valgrind_cmd="valgrind -q --trace-children=yes --error-exitcode=1 --run-libc-freeres=no"
@@ -300,6 +301,7 @@ typeiter_LDADD = $(libdw) $(libelf) $(libmudflap)
low_high_pc_LDADD = $(libdw) $(libelf) $(libmudflap)
test_elf_cntl_gelf_getshdr_LDADD = $(libelf) $(libmudflap)
dwflsyms_LDADD = $(libdw) $(libelf) $(libmudflap)
+dwfllines_LDADD = $(libdw) $(libelf) $(libmudflap)
if GCOV
check: check-am coverage
diff --git a/tests/dwfllines.c b/tests/dwfllines.c
new file mode 100644
index 0000000..90379dd
--- /dev/null
+++ b/tests/dwfllines.c
@@ -0,0 +1,164 @@
+/* Copyright (C) 2013 Red Hat, Inc.
+ This file is part of elfutils.
+
+ This file is free software; you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation; either version 3 of the License, or
+ (at your option) any later version.
+
+ elfutils is distributed in the hope that it will be useful, but
+ WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <inttypes.h>
+#include <assert.h>
+#include ELFUTILS_HEADER(dw)
+#include ELFUTILS_HEADER(dwfl)
+#include <dwarf.h>
+#include <argp.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+#include <error.h>
+
+int
+main (int argc, char *argv[])
+{
+ int cnt;
+
+ Dwfl *dwfl = NULL;
+ (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &cnt, &dwfl);
+ assert (dwfl != NULL);
+
+ Dwarf_Die *cu = NULL;
+ Dwarf_Addr bias;
+ do
+ {
+ cu = dwfl_nextcu (dwfl, cu, &bias);
+ if (cu != NULL)
+ {
+ Dwfl_Module *mod = dwfl_cumodule (cu);
+ const char *modname = (dwfl_module_info (mod, NULL, NULL, NULL,
+ NULL, NULL, NULL, NULL)
+ ?: "<unknown>");
+ const char *cuname = (dwarf_diename (cu) ?: "<unknown>");
+
+ printf ("mod: %s CU: [%" PRIx64 "] %s\n", modname,
+ dwarf_dieoffset (cu), cuname);
+
+ size_t lines;
+ if (dwfl_getsrclines (cu, &lines) != 0)
+ continue; // No lines...
+
+ for (size_t i = 0; i < lines; i++)
+ {
+ Dwfl_Line *line = dwfl_onesrcline (cu, i);
+
+ Dwarf_Addr addr;
+ int lineno;
+ int colno;
+ Dwarf_Word mtime;
+ Dwarf_Word length;
+ const char *src = dwfl_lineinfo (line, &addr, &lineno, &colno,
+ &mtime, &length);
+
+ Dwarf_Addr dw_bias;
+ Dwarf_Line *dw_line = dwfl_dwarf_line (line, &dw_bias);
+ assert (bias == dw_bias);
+
+ Dwarf_Addr dw_addr;
+ if (dwarf_lineaddr (dw_line, &dw_addr) != 0)
+ error (EXIT_FAILURE, 0, "dwarf_lineaddr: %s",
+ dwarf_errmsg (-1));
+ assert (addr == dw_addr + dw_bias);
+
+ unsigned int dw_op_index;
+ if (dwarf_lineop_index (dw_line, &dw_op_index) != 0)
+ error (EXIT_FAILURE, 0, "dwarf_lineop_index: %s",
+ dwarf_errmsg (-1));
+
+ int dw_lineno;
+ if (dwarf_lineno (dw_line, &dw_lineno) != 0)
+ error (EXIT_FAILURE, 0, "dwarf_lineno: %s",
+ dwarf_errmsg (-1));
+ assert (lineno == dw_lineno);
+
+ int dw_colno;
+ if (dwarf_linecol (dw_line, &dw_colno) != 0)
+ error (EXIT_FAILURE, 0, "dwarf_lineno: %s",
+ dwarf_errmsg (-1));
+ assert (colno == dw_colno);
+
+ bool begin;
+ if (dwarf_linebeginstatement (dw_line, &begin) != 0)
+ error (EXIT_FAILURE, 0, "dwarf_linebeginstatement: %s",
+ dwarf_errmsg (-1));
+
+ bool end;
+ if (dwarf_lineendsequence (dw_line, &end) != 0)
+ error (EXIT_FAILURE, 0, "dwarf_lineendsequence: %s",
+ dwarf_errmsg (-1));
+
+ bool pend;
+ if (dwarf_lineprologueend (dw_line, &pend) != 0)
+ error (EXIT_FAILURE, 0, "dwarf_lineprologueend: %s",
+ dwarf_errmsg (-1));
+
+ bool ebegin;
+ if (dwarf_lineepiloguebegin (dw_line, &ebegin) != 0)
+ error (EXIT_FAILURE, 0, "dwarf_lineepiloguebegin: %s",
+ dwarf_errmsg (-1));
+
+ bool block;
+ if (dwarf_lineblock (dw_line, &block) != 0)
+ error (EXIT_FAILURE, 0, "dwarf_lineblock: %s",
+ dwarf_errmsg (-1));
+
+ unsigned int isa;
+ if (dwarf_lineisa (dw_line, &isa) != 0)
+ error (EXIT_FAILURE, 0, "dwarf_lineisa: %s",
+ dwarf_errmsg (-1));
+
+ unsigned int disc;
+ if (dwarf_linediscriminator (dw_line, &disc) != 0)
+ error (EXIT_FAILURE, 0, "dwarf_linediscriminator: %s",
+ dwarf_errmsg (-1));
+
+ const char *dw_src;
+ Dwarf_Word dw_mtime;
+ Dwarf_Word dw_length;
+ dw_src = dwarf_linesrc (dw_line, &dw_mtime, &dw_length);
+ assert (strcmp (src, dw_src) == 0);
+ assert (mtime == dw_mtime);
+ assert (length == dw_length);
+
+ printf ("%zd %#" PRIx64 " %s:%d:%d\n"
+ " time: %#" PRIX64 ", len: %" PRIu64
+ ", idx: %d, b: %d, e: %d"
+ ", pe: %d, eb: %d, block: %d"
+ ", isa: %d, disc: %d\n",
+ i, addr, src, lineno, colno, mtime, length,
+ dw_op_index, begin, end, pend, ebegin, block, isa, disc);
+
+ Dwarf_Die *linecu = dwfl_linecu (line);
+ assert (cu == linecu);
+
+ Dwfl_Module *linemod = dwfl_linemodule (line);
+ assert (mod == linemod);
+ }
+ }
+ }
+ while (cu != NULL);
+
+ dwfl_end (dwfl);
+
+ return 0;
+}
diff --git a/tests/run-dwfllines.sh b/tests/run-dwfllines.sh
new file mode 100755
index 0000000..df7d16f
--- /dev/null
+++ b/tests/run-dwfllines.sh
@@ -0,0 +1,88 @@
+#! /bin/sh
+# Copyright (C) 2013 Red Hat, Inc.
+# This file is part of elfutils.
+#
+# This file is free software; you can redistribute it and/or modify
+# it under the terms of the GNU General Public License as published by
+# the Free Software Foundation; either version 3 of the License, or
+# (at your option) any later version.
+#
+# elfutils is distributed in the hope that it will be useful, but
+# WITHOUT ANY WARRANTY; without even the implied warranty of
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+# GNU General Public License for more details.
+#
+# You should have received a copy of the GNU General Public License
+# along with this program. If not, see <http://www.gnu.org/licenses/>.
+
+. $srcdir/test-subr.sh
+
+testfiles testfile testfile2
+
+testrun_compare ./dwfllines -e testfile <<\EOF
+mod: CU: [b] m.c
+0 0x804842c /home/drepper/gnu/new-bu/build/ttt/m.c:5:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+1 0x8048432 /home/drepper/gnu/new-bu/build/ttt/m.c:6:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+2 0x804844d /home/drepper/gnu/new-bu/build/ttt/m.c:7:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+3 0x8048458 /home/drepper/gnu/new-bu/build/ttt/m.c:8:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+4 0x804845a /home/drepper/gnu/new-bu/build/ttt/m.c:8:0
+ time: 0, len: 0, idx: 0, b: 1, e: 1, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+mod: CU: [ca] b.c
+0 0x804845c /home/drepper/gnu/new-bu/build/ttt/b.c:4:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+1 0x804845f /home/drepper/gnu/new-bu/build/ttt/b.c:5:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+2 0x8048464 /home/drepper/gnu/new-bu/build/ttt/b.c:6:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+3 0x8048466 /home/drepper/gnu/new-bu/build/ttt/b.c:6:0
+ time: 0, len: 0, idx: 0, b: 1, e: 1, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+mod: CU: [15fc] f.c
+0 0x8048468 /home/drepper/gnu/new-bu/build/ttt/f.c:3:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+1 0x804846b /home/drepper/gnu/new-bu/build/ttt/f.c:4:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+2 0x8048470 /home/drepper/gnu/new-bu/build/ttt/f.c:5:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+3 0x8048472 /home/drepper/gnu/new-bu/build/ttt/f.c:5:0
+ time: 0, len: 0, idx: 0, b: 1, e: 1, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+EOF
+
+testrun_compare ./dwfllines -e testfile2 <<\EOF
+mod: CU: [b] b.c
+0 0x10000470 /shoggoth/drepper/b.c:4:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+1 0x1000047c /shoggoth/drepper/b.c:5:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+2 0x10000480 /shoggoth/drepper/b.c:6:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+3 0x10000490 /shoggoth/drepper/b.c:6:0
+ time: 0, len: 0, idx: 0, b: 1, e: 1, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+mod: CU: [97d] f.c
+0 0x10000490 /shoggoth/drepper/f.c:3:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+1 0x1000049c /shoggoth/drepper/f.c:4:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+2 0x100004a0 /shoggoth/drepper/f.c:5:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+3 0x100004b0 /shoggoth/drepper/f.c:5:0
+ time: 0, len: 0, idx: 0, b: 1, e: 1, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+mod: CU: [9e4] m.c
+0 0x100004b0 /shoggoth/drepper/m.c:5:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+1 0x100004cc /shoggoth/drepper/m.c:6:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+2 0x100004e8 /shoggoth/drepper/m.c:7:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+3 0x100004f4 /shoggoth/drepper/m.c:8:0
+ time: 0, len: 0, idx: 0, b: 1, e: 0, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+4 0x10000514 /shoggoth/drepper/m.c:8:0
+ time: 0, len: 0, idx: 0, b: 1, e: 1, pe: 0, eb: 0, block: 0, isa: 0, disc: 0
+EOF
+
+testrun_on_self_quiet ./dwfllines -e
+
+exit 0
--
1.8.1.4
11 years, 1 month
[PATCH] readelf: Accept version 8 .gdb_index section format. Fix memory leak.
by Mark Wielaard
Version 8 just indicates that if the .gdb_index was generated by the gold
linker it correctly includes TUs for symbols. http://sourceware.org/PR15021
Also fix memory leak by freeing the return value of format_dwarf_addr.
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
src/ChangeLog | 5 +++++
src/readelf.c | 9 ++++++---
2 files changed, 11 insertions(+), 3 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index 2275c5c..237da49 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,8 @@
+2013-03-18 Mark Wielaard <mjw(a)redhat.com>
+
+ * readelf.c (print_gdb_index_section): Accept version 8. Free
+ format_dwarf_addr results.
+
2013-03-01 Mark Wielaard <mjw(a)redhat.com>
* findtextrel.c (process_file): Release ELF and close file when not
diff --git a/src/readelf.c b/src/readelf.c
index c04cd20..774318f 100644
--- a/src/readelf.c
+++ b/src/readelf.c
@@ -1,5 +1,5 @@
/* Print information from ELF file in human-readable form.
- Copyright (C) 1999-2012 Red Hat, Inc.
+ Copyright (C) 1999-2013 Red Hat, Inc.
This file is part of elfutils.
Written by Ulrich Drepper <drepper(a)redhat.com>, 1999.
@@ -7272,8 +7272,9 @@ print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
// The only difference between version 4 and version 5 is the
// hash used for generating the table. Version 6 contains symbols
- // for inlined functions, older versions didn't.
- if (vers < 4 || vers > 7)
+ // for inlined functions, older versions didn't. Version 7 adds
+ // symbol kinds.
+ if (vers < 4 || vers > 8)
{
printf (gettext (" unknown version, cannot parse section\n"));
return;
@@ -7387,6 +7388,8 @@ print_gdb_index_section (Dwfl_Module *dwflmod, Ebl *ebl, GElf_Ehdr *ehdr,
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);
n++;
}
--
1.8.1.4
11 years, 1 month
dwarf_getfuncs () and dwarf_func_inline_instances () vs partial_units
by Mark Wielaard
Hi,
In some cases dwz might place a DW_TAG_subprogram in a partial_unit that
is then imported into different compile_units that use it for
DW_TAG_inlined_subroutines.
Currently there is no way to get at these through dwarf_getfuncs ()
since that function only accepts DW_TAG_compile_unit DIEs, and doesn't
follow DW_TAG_import units.
If we change dwarf_getfuncs () to either accept a partial_unit DIEs or
by descending into imported_units the subprogram DIEs it returns will
have their Dwarf_CU point to the partial_unit. This means that
dwarf_func_inline_instances () for those DIEs will only return any
inlined_subroutines pointing to the subprogram inside the partial_unit
itself (if any). It will miss the inlined_subroutines in the
compile_units that import the partial_unit since it will start its
search in the func DIE (partial) unit.
Any thoughts on how (or if) we should fix this?
I think the easiest way to fix this is to make dwarf_getfuncs () recurse
into DW_TAG_imported_units and return any (top-level) subprogram DIE
that way. Then for dwarf_func_inline_instances () if we notice the func
DIE has a partial_unit as CU we just search all compile_unit CUs instead
of just the defining CU.
Should we also accept DW_TAG_partial_units as root for dwarf_getfuncs?
Any alternative approaches to solve this issue? I can imagine having a
dwarf_func_inline_instances () that takes a CU as argument to search in,
instead of the func defining CU. But that introduces a new interface and
would not be very intuitive for the user (though it might be more
efficient than searching all CUs).
Thanks,
Mark
11 years, 1 month
[PATCH] Fix two memory leaks in findtextrel and strip.
by Mark Wielaard
The findtextrel leak is real, when processing lots of files without text
relocations the files and memory wouldn't be released. The strip leak is
minor since it can only happen when using -f which only allows one file
as argument. But it is nice to see valgrind say:
"All heap blocks were freed -- no leaks are possible".
Signed-off-by: Mark Wielaard <mjw(a)redhat.com>
---
src/ChangeLog | 7 +++++++
src/findtextrel.c | 2 +-
src/strip.c | 7 ++++++-
3 files changed, 14 insertions(+), 2 deletions(-)
diff --git a/src/ChangeLog b/src/ChangeLog
index 6e219e6..2275c5c 100644
--- a/src/ChangeLog
+++ b/src/ChangeLog
@@ -1,3 +1,10 @@
+2013-03-01 Mark Wielaard <mjw(a)redhat.com>
+
+ * findtextrel.c (process_file): Release ELF and close file when not
+ text relocations are found.
+ * strip.c (handle_elf): Track memory used for .debuglink section data
+ and free when done.
+
2013-02-24 Mark Wielaard <mjw(a)redhat.com>
* elflint.c (check_symtab): Add __bss_start__ to the list of symbols
diff --git a/src/findtextrel.c b/src/findtextrel.c
index 39f7c92..9fd8163 100644
--- a/src/findtextrel.c
+++ b/src/findtextrel.c
@@ -311,7 +311,7 @@ process_file (const char *fname, bool more_than_one)
if (!have_textrel)
{
error (0, 0, gettext ("no text relocations reported in '%s'"), fname);
- return 1;
+ goto err_elf_close;
}
int fd2 = -1;
diff --git a/src/strip.c b/src/strip.c
index 5e9c883..05adc20 100644
--- a/src/strip.c
+++ b/src/strip.c
@@ -432,6 +432,7 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
Elf_Data debuglink_crc_data;
bool any_symtab_changes = false;
Elf_Data *shstrtab_data = NULL;
+ void *debuglink_buf = NULL;
/* Create the full name of the file. */
if (prefix != NULL)
@@ -1046,7 +1047,8 @@ handle_elf (int fd, Elf *elf, const char *prefix, const char *fname,
shdr_info[cnt].data->d_align = 4;
shdr_info[cnt].shdr.sh_size = shdr_info[cnt].data->d_size
= crc_offset + 4;
- shdr_info[cnt].data->d_buf = xcalloc (1, shdr_info[cnt].data->d_size);
+ debuglink_buf = xcalloc (1, shdr_info[cnt].data->d_size);
+ shdr_info[cnt].data->d_buf = debuglink_buf;
strcpy (shdr_info[cnt].data->d_buf, debug_basename);
@@ -2013,6 +2015,9 @@ while computing checksum for debug information"));
free (shdr_info[cnt].debug_data->d_buf);
}
+ /* Free data we allocated for the .gnu_debuglink section. */
+ free (debuglink_buf);
+
/* Free the memory. */
if ((shnum + 2) * sizeof (struct shdr_info) > MAX_STACK_ALLOC)
free (shdr_info);
--
1.7.1
11 years, 1 month