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] 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


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