Hello community,

here is the log from the commit of package dwz for openSUSE:Factory checked in 
at 2020-01-23 16:08:00
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++
Comparing /work/SRC/openSUSE:Factory/dwz (Old)
 and      /work/SRC/openSUSE:Factory/.dwz.new.26092 (New)
++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Package is "dwz"

Thu Jan 23 16:08:00 2020 rev:11 rq:765149 version:0.13

Changes:
--------
--- /work/SRC/openSUSE:Factory/dwz/dwz.changes  2019-12-07 15:12:01.675824394 
+0100
+++ /work/SRC/openSUSE:Factory/.dwz.new.26092/dwz.changes       2020-01-23 
16:08:06.363536001 +0100
@@ -1,0 +2,6 @@
+Fri Jan 17 06:30:58 UTC 2020 - Tom de Vries <[email protected]>
+
+- Fix reference from compilation unit to partial unit [swo#25398].
+  * dwz-fix-reference-from-pu-to-cu.patch
+
+-------------------------------------------------------------------

New:
----
  dwz-fix-reference-from-pu-to-cu.patch

++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++

Other differences:
------------------
++++++ dwz.spec ++++++
--- /var/tmp/diff_new_pack.z9VyT7/_old  2020-01-23 16:08:07.455536648 +0100
+++ /var/tmp/diff_new_pack.z9VyT7/_new  2020-01-23 16:08:07.459536650 +0100
@@ -1,7 +1,7 @@
 #
 # spec file for package dwz
 #
-# Copyright (c) 2019 SUSE LINUX GmbH, Nuernberg, Germany.
+# Copyright (c) 2020 SUSE LINUX GmbH, Nuernberg, Germany.
 #
 # All modifications and additions to the file contributed by third parties
 # remain the property of their copyright owners, unless otherwise agreed
@@ -77,6 +77,7 @@
 Patch2:         dwz-fix-die-no-multifile-propagation.patch
 Patch3:         dwz-fix-assertion-off-cu_size-in-recompute_abbrevs.patch
 Patch4:         dwz-fix-refd-NULL-assertion-in-write_die.patch
+Patch5:         dwz-fix-reference-from-pu-to-cu.patch
 
 %if %{build_main}
 %description
@@ -109,6 +110,7 @@
 %patch2 -p1
 %patch3 -p1
 %patch4 -p1
+%patch5 -p1
 
 %build
 make %{?_smp_mflags} CFLAGS="%{optflags}"

++++++ dwz-fix-reference-from-pu-to-cu.patch ++++++
Fix reference from PU to CU

[ Backport of master commit bce3238. ]

Consider the following situation:
- we have two duplicate chains: {A, B} and {C, D, E}
- each duplicate chain has a representant: A' and C'
- there's a pseudo-ref from Z to D, which is using one of the CU-local dwarf
  operators DW_OP_GNU_{{regval,deref,const}_type,convert,reinterpret} (which
  is summarized in the code by setting D->die_op_type_referenced).

Schematically this looks like this:
...
(A') --------d-------> (A) --d--> (B)
                        |          |
                        r          r
                        |          |
                        v          v
(C') --d--> (C) --d--> (D) --d--> (E)
                        ^
                        |
                        pr
                        |
                       (Z)
...

Because the die D is referenced using a CU-local dwarf operator, the die is
kept in the CU (even though it's part of a duplicate chain), to keep the
pseudo-ref valid.  Also other CU-local refs to D keep pointing to D.

A situation however arises while writing out A' to a partial unit using A as
template, when we try to write out the reference to D, and arrive here in
in write_die with die == A', ref == A, refd == D and refdt == D:
...
                  if (refdt->die_dup && refdt->die_op_type_referenced)
                    {
                      if (cu == die_cu (refdt->die_dup))
                        refd = die_find_dup (refdt, refdt->die_dup, refd);
                    }
                  else if (refdt->die_dup)
                    refd = die_find_dup (refdt, refdt->die_dup, refd);
...

The first if condition evaluates to true because D->die_dup == C' and
D->die_op_type_referenced == 1.

But the following (nested) if condition evalutes to false, because A' and C'
are not part of the same unit.

Consequently, refd remains D, and we get a reference from a die in a partial
unit (A') to a die in a compilation unit (D):
...
(A') --------d--------> (A) --d--> (B)
    \                    |          |
     +---------------+   r          r
                      \  |          |
                       v v          v
(C') --d--> (C) --d--> (D) ---d--> (E)
                        ^
                        |
                        pr
                        |
                       (Z)
...

The behaviour that is triggered is one that is valid for writing out A, but is
incorrect because in fact we're writing out A' using A as template.  Note that
this problem would not have occurred if the pseudo-reference pointed to E
instead, in which case we would have had the expected reference from A' to C'.

Fix this by detecting that we're writing out A' (in other words,
cu->cu_kind == CU_PU), and skipping the die_op_type_referenced
handling in that case, resulting in a reference from A' to C'.

2020-01-16  Tom de Vries  <[email protected]>

        PR dwz/25398
        * dwz.c (write_die): Skip die_op_type_referenced handling if
        cu->cu_kind == CU_PU.

---
 dwz.c | 3 ++-
 1 file changed, 2 insertions(+), 1 deletion(-)

diff --git a/dwz.c b/dwz.c
index c7db337..298bca1 100644
--- a/dwz.c
+++ b/dwz.c
@@ -9301,7 +9301,8 @@ write_die (unsigned char *ptr, dw_cu_ref cu, dw_die_ref 
die,
                  refdt = refd;
                  while (refdt->die_toplevel == 0)
                    refdt = refdt->die_parent;
-                 if (refdt->die_dup && refdt->die_op_type_referenced)
+                 if (refdt->die_dup && refdt->die_op_type_referenced
+                     && cu->cu_kind != CU_PU)
                    {
                      if (cu == die_cu (refdt->die_dup))
                        refd = die_find_dup (refdt, refdt->die_dup, refd);

Reply via email to