[PATCH] Add --devel-no-checksum-cycle-opt

Tom de Vries tdevries@suse.de
Tue Feb 23 08:01:42 GMT 2021


Hi,

In checksum_ref_die, we need to determine a per-toplevel-die checksum based on
the inter-toplevel-die references.  It has four modes:
- mode 1, a trivial one in which we walk towards toplevel-dies.
- mode 2, in which we optimistically assume that there are no cycles.
  If that is the case, we're done.  Otherwise, we use either mode 3 or mode 4.
- mode 3, dealing with cycles in a faster way
- mode 4, dealing with cycles

I did some testing using the testsuite and external testsuite and found that
mode 4 was not triggered once.  I'm not quite sure how to construct a
test-case for that either.

Add an option --devel-no-checksum-cycle-opt that can be used to enforce using
mode 3 instead of mode 4, and add a test-case that uses it.

Any comments?

Thanks,
- Tom

Add --devel-no-checksum-cycle-opt

2021-02-23  Tom de Vries  <tdevries@suse.de>

	PR dwz/27429
	* Makefile (TEST_EXECS): Add cycle.
	(cycle): New target.
	* dwz.c (checksum_cycle_opt): New var.
	(checksum_ref_die): Handle checksum_cycle_opt.
	(dwz_options, usage): Add --devel-checksum-cycle-opt entries.
	* testsuite/dwz.tests/cycle.c: New test.
	* testsuite/dwz.tests/cycle.sh: New test.

---
 Makefile                     |  5 ++++-
 dwz.c                        |  8 +++++++-
 testsuite/dwz.tests/cycle.c  | 13 +++++++++++++
 testsuite/dwz.tests/cycle.sh | 27 +++++++++++++++++++++++++++
 4 files changed, 51 insertions(+), 2 deletions(-)

diff --git a/Makefile b/Makefile
index d320266..337a58a 100644
--- a/Makefile
+++ b/Makefile
@@ -32,7 +32,7 @@ TEST_EXECS_x86_64 = py-section-script dw2-skip-prologue \
 TEST_EXECS = hello dwz-for-test min two-typedef start hello-gold-gdb-index \
 	start-gold hello-gnu-pubnames $(TEST_EXECS_DWARF_ASM) \
 	$(TEST_EXECS_$(UNAME)) odr-struct odr-class odr-union odr-struct-ns \
-	odr-class-ns odr-union-ns odr-loc def-decl
+	odr-class-ns odr-union-ns odr-loc def-decl cycle
 
 UNAME:=$(shell uname -p)
 
@@ -131,6 +131,9 @@ def-decl:
 	$(CXX) $(TEST_SRC)/decl.cc $(TEST_SRC)/def.cc $(TEST_SRC)/def2.cc \
 	  -I$(TEST_SRC) -o $@ -g
 
+cycle:
+	$(CC) $(TEST_SRC)/cycle.c -o $@ -g
+
 # On some systems we need to set and export DEJAGNU to suppress
 # WARNING: Couldn't find the global config file.
 DEJAGNU ?= /dev/null
diff --git a/dwz.c b/dwz.c
index 0e9ca2a..d3183cc 100644
--- a/dwz.c
+++ b/dwz.c
@@ -195,6 +195,7 @@ static int dump_pus_p;
 static int verify_dups_p;
 static int verify_edge_freelist;
 static int stats_p;
+static int checksum_cycle_opt = 1;
 #else
 #define tracing 0
 #define ignore_size 0
@@ -205,6 +206,7 @@ static int stats_p;
 #define dump_pus_p 0
 #define verify_dups_p 0
 #define stats_p 0
+#define checksum_cycle_opt 1
 #endif
 static int unoptimized_multifile;
 static int save_temps = 0;
@@ -4333,7 +4335,7 @@ checksum_ref_die (dw_cu_ref cu, dw_die_ref top_die, dw_die_ref die,
 		    }
 		}
 	    }
-	  if (minidx != -1U)
+	  if (checksum_cycle_opt && minidx != -1U)
 	    {
 	      idx = 0;
 	      checksum_ref_die (die_cu (arr[minidx]), arr[minidx],
@@ -16194,6 +16196,10 @@ static struct option dwz_options[] =
 			 no_argument,	    &gen_cu_p, 1 },
   { "devel-no-gen-cu",
 			 no_argument,	    &gen_cu_p, 0 },
+  { "devel-checksum-cycle-opt",
+			 no_argument,	    &checksum_cycle_opt, 1 },
+  { "devel-no-checksum-cycle-opt",
+			 no_argument,	    &checksum_cycle_opt, 0 },
 #endif
   { "odr",		 no_argument,	    &odr, 1 },
   { "no-odr",		 no_argument,	    &odr, 0 },
diff --git a/testsuite/dwz.tests/cycle.c b/testsuite/dwz.tests/cycle.c
new file mode 100644
index 0000000..4795a79
--- /dev/null
+++ b/testsuite/dwz.tests/cycle.c
@@ -0,0 +1,13 @@
+struct s;
+
+struct s {
+  struct s *p;
+};
+
+struct s var;
+
+int
+main (void)
+{
+  return 0;
+}
diff --git a/testsuite/dwz.tests/cycle.sh b/testsuite/dwz.tests/cycle.sh
new file mode 100644
index 0000000..722e6ad
--- /dev/null
+++ b/testsuite/dwz.tests/cycle.sh
@@ -0,0 +1,27 @@
+cp $execs/cycle 1
+
+# Using mode 3 in checksum_die_ref.
+dwz 1 -o 1.z --devel-dump-dies 2> DUMP.1
+rm -f 1.z
+
+# Skipping mode 3 in checksum_die_ref.
+dwz 1 -o 1.z --devel-dump-dies --devel-no-checksum-cycle-opt 2> DUMP.2
+rm -f 1.z
+
+# Verify that mode 3 and mode 4 have different checksums.
+grep " s structure_type" DUMP.1 > LINE.1
+grep " s structure_type" DUMP.2 > LINE.2
+! diff -q LINE.1 LINE.2
+rm -f DUMP.1 DUMP.2 LINE.1 LINE.2
+
+# Verify that dwz actually works with --devel-no-checksum-cycle-opt.
+cp 1 2
+dwz -m 3 1 2 --devel-no-checksum-cycle-opt --devel-ignore-size
+
+cnt=$(readelf -wi 3 | grep -c "DW_AT_name.*: s$")
+[ $cnt -eq 1 ]
+
+cnt=$(readelf -wi 1 | grep -c "DW_AT_name.*: s$" || true)
+[ $cnt -eq 0 ]
+
+rm -f 1 2 3


More information about the Dwz mailing list