]> git.ipfire.org Git - thirdparty/elfutils.git/commitdiff
libdw and libdwfl srcfiles and srclines fixes for partial_units.
authorMark Wielaard <mjw@redhat.com>
Tue, 12 Mar 2013 11:02:51 +0000 (12:02 +0100)
committerMark Wielaard <mjw@redhat.com>
Tue, 12 Mar 2013 11:25:25 +0000 (12:25 +0100)
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
libdw/dwarf_getsrcfiles.c
libdw/dwarf_getsrclines.c
libdwfl/ChangeLog
libdwfl/dwfl_getsrclines.c
tests/ChangeLog
tests/Makefile.am
tests/dwfllines.c [new file with mode: 0644]
tests/run-dwfllines.sh [new file with mode: 0755]

index 2900ef6c42fed246fa89e904b8a92baa01353be2..16acf5cd3ce3eff006431722e9a04023f06d9d5e 100644 (file)
@@ -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,
index d026820487d691381ba64f7b2a0e615f9080bf5c..4bfc34b8b48031e5e81978565d9a979a78a5856f 100644 (file)
@@ -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;
index 0758023fb6934619680d130e6eda73d26ac0f2d1..c24aebb59252368f4782337c9eb40e04e562c8d0 100644 (file)
@@ -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;
index 78139ba503e9501754627deebbc2fea2fcf73367..15a6c9c9e4a1fcd6ab32d3a1286c0eade66efede 100644 (file)
@@ -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
index cc8cb7cf15a0385d8ca12f61618213c13f09e747..bdfcf5c6a0fead6a5a070f1a8e8568b523152f19 100644 (file)
@@ -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;
 }
index d181cd567866d7adc4f8bcc4a6d1fd0ef99c8a6a..ca06a55c22ab33732031c9c7bb28f124b436d5eb 100644 (file)
@@ -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.
index 63184f80d05f71e4696f40364b342ec542700c7d..a5f7a8c0d538f68f31349ce8b9557a56742f9bed 100644 (file)
@@ -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 (file)
index 0000000..90379dd
--- /dev/null
@@ -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 (executable)
index 0000000..df7d16f
--- /dev/null
@@ -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