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: Fix dwarf_peel_type infinite loop.


We were calling dwarf_attr_integrate () in the die in the loop instead of
on the result. Which would cause an infinite loop when die != result.
Add a testcase that explicitly checks this case.

https://sourceware.org/bugzilla/show_bug.cgi?id=21330

Signed-off-by: Mark Wielaard <mark@klomp.org>
---
 libdw/ChangeLog         |   5 ++
 libdw/dwarf_peel_type.c |   2 +-
 tests/ChangeLog         |   9 ++++
 tests/Makefile.am       |   9 ++--
 tests/peel_type.c       | 119 ++++++++++++++++++++++++++++++++++++++++++++++++
 tests/run-peel-type.sh  |  62 +++++++++++++++++++++++++
 6 files changed, 202 insertions(+), 4 deletions(-)
 create mode 100644 tests/peel_type.c
 create mode 100755 tests/run-peel-type.sh

diff --git a/libdw/ChangeLog b/libdw/ChangeLog
index 978b991..3f63a17 100644
--- a/libdw/ChangeLog
+++ b/libdw/ChangeLog
@@ -1,3 +1,8 @@
+2017-03-30  Mark Wielaard  <mjw@redhat.com>
+
+	* dwarf_peel_type.c (dwarf_peel_type): Call dwarf_attr_integrate on
+	result.
+
 2016-10-22  Mark Wielaard  <mjw@redhat.com>
 
 	* dwarf.h: Correct spelling of DW_LANG_PLI. Add compatibility define.
diff --git a/libdw/dwarf_peel_type.c b/libdw/dwarf_peel_type.c
index 5dca8f8..9735694 100644
--- a/libdw/dwarf_peel_type.c
+++ b/libdw/dwarf_peel_type.c
@@ -53,7 +53,7 @@ dwarf_peel_type (Dwarf_Die *die, Dwarf_Die *result)
 	 || tag == DW_TAG_atomic_type)
     {
       Dwarf_Attribute attr_mem;
-      Dwarf_Attribute *attr = INTUSE (dwarf_attr_integrate) (die, DW_AT_type,
+      Dwarf_Attribute *attr = INTUSE (dwarf_attr_integrate) (result, DW_AT_type,
 							     &attr_mem);
       if (attr == NULL)
 	return 1;
diff --git a/tests/ChangeLog b/tests/ChangeLog
index e6656c7..901ed1c 100644
--- a/tests/ChangeLog
+++ b/tests/ChangeLog
@@ -1,3 +1,12 @@
+2017-03-30  Mark Wielaard  <mark@klomp.org>
+
+	* peel_type.c: New file.
+	* run-peel-type.sh: New test.
+	* Makefile.am (check_PROGRAMS): Add peel_type.c.
+	(TESTS): Add run-peel-type.sh.
+	(EXTRA_DIST): Likewise.
+	(peel_type_LDADD): New variable.
+
 2017-02-15  Mark Wielaard  <mark@klomp.org>
 
 	* Makefile.am (EXTRA_DIST): Add testfileppc64attrs.o.bz2.
diff --git a/tests/Makefile.am b/tests/Makefile.am
index a27e868..02906fc 100644
--- a/tests/Makefile.am
+++ b/tests/Makefile.am
@@ -50,7 +50,8 @@ check_PROGRAMS = arextract arsymtest newfile saridx scnnames sectiondump \
 		  test-elf_cntl_gelf_getshdr dwflsyms dwfllines \
 		  dwfl-report-elf-align varlocs backtrace backtrace-child \
 		  backtrace-data backtrace-dwarf debuglink debugaltlink \
-		  buildid deleted deleted-lib.so aggregate_size vdsosyms \
+		  buildid deleted deleted-lib.so aggregate_size peel_type \
+		  vdsosyms \
 		  getsrc_die strptr newdata elfstrtab dwfl-proc-attach \
 		  elfshphehdr elfstrmerge dwelfgnucompressed elfgetchdr \
 		  elfgetzdata elfputzdata zstrptr emptyfile vendorelf
@@ -120,7 +121,8 @@ TESTS = run-arextract.sh run-arsymtest.sh newfile test-nlist \
 	run-backtrace-demangle.sh run-stack-d-test.sh run-stack-i-test.sh \
 	run-stack-demangled-test.sh run-readelf-zx.sh run-readelf-zp.sh \
 	run-readelf-dwz-multi.sh run-allfcts-multi.sh run-deleted.sh \
-	run-linkmap-cut.sh run-aggregate-size.sh vdsosyms run-readelf-A.sh \
+	run-linkmap-cut.sh run-aggregate-size.sh run-peel-type.sh \
+	vdsosyms run-readelf-A.sh \
 	run-getsrc-die.sh run-strptr.sh newdata elfstrtab dwfl-proc-attach \
 	elfshphehdr run-lfs-symbols.sh run-dwelfgnucompressed.sh \
 	run-elfgetchdr.sh \
@@ -315,7 +317,7 @@ EXTRA_DIST = run-arextract.sh run-arsymtest.sh \
 	     run-deleted.sh run-linkmap-cut.sh linkmap-cut-lib.so.bz2 \
 	     linkmap-cut.bz2 linkmap-cut.core.bz2 \
 	     run-aggregate-size.sh testfile-sizes1.o.bz2 testfile-sizes2.o.bz2 \
-	     testfile-sizes3.o.bz2 \
+	     testfile-sizes3.o.bz2 run-peel-type.sh \
 	     run-readelf-A.sh testfileppc32attrs.o.bz2 \
 	     testfilesparc64attrs.o.bz2 testfileppc64attrs.o.bz2 \
 	     testfile-debug-types.bz2 \
@@ -473,6 +475,7 @@ deleted_LDADD = ./deleted-lib.so
 deleted_lib_so_LDFLAGS = -shared -rdynamic
 deleted_lib_so_CFLAGS = -fPIC -fasynchronous-unwind-tables
 aggregate_size_LDADD = $(libdw) $(libelf) $(argp_LDADD)
+peel_type_LDADD = $(libdw) $(libelf) $(argp_LDADD)
 vdsosyms_LDADD = $(libdw) $(libelf)
 getsrc_die_LDADD = $(libdw) $(libelf)
 strptr_LDADD = $(libelf)
diff --git a/tests/peel_type.c b/tests/peel_type.c
new file mode 100644
index 0000000..bccce32
--- /dev/null
+++ b/tests/peel_type.c
@@ -0,0 +1,119 @@
+/* Test program for dwarf_peel_type. Peels type of top-level vars.
+   Copyright (C) 2017 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 <assert.h>
+#include <argp.h>
+#include <inttypes.h>
+#include <fcntl.h>
+#include ELFUTILS_HEADER(dw)
+#include ELFUTILS_HEADER(dwfl)
+#include <stdio.h>
+#include <unistd.h>
+#include <dwarf.h>
+
+#include "../libdw/known-dwarf.h"
+
+static const char *
+dwarf_tag_string (unsigned int tag)
+{
+  switch (tag)
+    {
+#define DWARF_ONE_KNOWN_DW_TAG(NAME, CODE) case CODE: return #NAME;
+      DWARF_ALL_KNOWN_DW_TAG
+#undef DWARF_ONE_KNOWN_DW_TAG
+    default:
+      return NULL;
+    }
+}
+
+void
+print_var_raw_type (Dwarf_Die *var)
+{
+  Dwarf_Attribute attr_mem;
+  Dwarf_Die type_mem;
+  Dwarf_Die *type;
+  const char *name = dwarf_diename (var);
+
+  type = dwarf_formref_die (dwarf_attr (var, DW_AT_type, &attr_mem),
+			    &type_mem);
+  if (type != NULL)
+    {
+      /* Test twice, once with a separate result DIE. Then with the
+	 DIE itself. The resulting tag should be the same. */
+      Dwarf_Die result_mem;
+      Dwarf_Die *result = &result_mem;
+      int res = dwarf_peel_type (type, result);
+      if (res < 0)
+        printf ("%s error peeling type: %s\n", name, dwarf_errmsg (-1));
+      else if (res > 0)
+	printf ("%s missing DW_TAG_TYPE, could peel further: %s\n",
+		name, dwarf_tag_string (dwarf_tag (result)));
+      else
+	{
+	  int tag = dwarf_tag (result);
+	  printf ("%s raw type %s\n", name, dwarf_tag_string (tag));
+	  res = dwarf_peel_type (type, type);
+	  if (res < 0)
+	    printf ("%s cannot peel type itself: %s\n", name,
+		    dwarf_errmsg (-1));
+	  else if (res > 0)
+	printf ("%s missing DW_TAG_TYPE, could peel type further: %s\n",
+		name, dwarf_tag_string (dwarf_tag (type)));
+	  else if (dwarf_tag (type) != tag)
+	    printf ("%s doesn't resolve the same: %s != %s\n", name,
+		    dwarf_tag_string (tag),
+		    dwarf_tag_string (dwarf_tag (type)));
+	}
+    }
+  else
+    printf ("%s has no type.\n", name);
+}
+
+int
+main (int argc, char *argv[])
+{
+
+  int remaining;
+  Dwfl *dwfl;
+  (void) argp_parse (dwfl_standard_argp (), argc, argv, 0, &remaining,
+                     &dwfl);
+  assert (dwfl != NULL);
+
+  Dwarf_Die *cu = NULL;
+  Dwarf_Addr dwbias;
+  while ((cu = dwfl_nextcu (dwfl, cu, &dwbias)) != NULL)
+    {
+      Dwarf_Die die_mem;
+      Dwarf_Die *die = &die_mem;
+      dwarf_child (cu, &die_mem);
+
+      while (1)
+	{
+	  if (dwarf_tag (die) == DW_TAG_variable)
+	    print_var_raw_type (die);
+
+	  if (dwarf_siblingof (die, &die_mem) != 0)
+	    break;
+	}
+    }
+
+  dwfl_end (dwfl);
+}
diff --git a/tests/run-peel-type.sh b/tests/run-peel-type.sh
new file mode 100755
index 0000000..7fd96e8
--- /dev/null
+++ b/tests/run-peel-type.sh
@@ -0,0 +1,62 @@
+#! /bin/sh
+# Copyright (C) 2017 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
+
+# See run-aggregate-size.sh for how to generate testfiles.
+
+testfiles testfile-sizes1.o testfile-sizes2.o testfile-sizes3.o
+
+testrun_compare ${abs_builddir}/peel_type -e testfile-sizes1.o <<\EOF
+c raw type base_type
+i raw type base_type
+l raw type base_type
+v raw type pointer_type
+s raw type structure_type
+ca raw type array_type
+ia raw type array_type
+va raw type array_type
+sa raw type array_type
+EOF
+
+testrun_compare ${abs_builddir}/peel_type -e testfile-sizes2.o <<\EOF
+c raw type base_type
+i raw type base_type
+l raw type base_type
+v raw type pointer_type
+s raw type structure_type
+ca raw type array_type
+ia raw type array_type
+va raw type array_type
+sa raw type array_type
+EOF
+
+testrun_compare ${abs_builddir}/peel_type -e testfile-sizes3.o <<\EOF
+c raw type base_type
+i raw type base_type
+l raw type base_type
+v raw type pointer_type
+s raw type structure_type
+ca raw type array_type
+ia raw type array_type
+va raw type array_type
+sa raw type array_type
+f raw type base_type
+b raw type base_type
+EOF
+
+exit 0
-- 
1.8.3.1


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