This is the mail archive of the
elfutils-devel@sourceware.org
mailing list for the elfutils project.
[PATCH] libdw and libdwfl srcfiles and srclines fixes for partial_units.
- From: Mark Wielaard <mjw at redhat dot com>
- To: elfutils-devel at lists dot fedorahosted dot org
- Date: Tue, 12 Mar 2013 12:30:43 +0100
- Subject: [PATCH] libdw and libdwfl srcfiles and srclines fixes for partial_units.
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@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@redhat.com>
+
+ * dwarf_getsrcfiles.c (dwarf_getsrcfiles): Allow DW_TAG_partial_unit.
+ * dwarf_getsrclines.c (dwarf_getsrclines): Likewise.
+
2013-02-15 Mark Wielaard <mjw@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@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@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@redhat.com>
+
+ * dwfl_getsrclines.c (dwfl_getsrclines): Return 0 on success.
+
2013-02-22 Mark Wielaard <mjw@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@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@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