Accepting request 765148 from home:tomdevries:branches:devel:tools:compiler-dwz-fix-ref-pu-to-cu
- Fix reference from compilation unit to partial unit [swo#25398]. * dwz-fix-reference-from-pu-to-cu.patch OBS-URL: https://build.opensuse.org/request/show/765148 OBS-URL: https://build.opensuse.org/package/show/devel:tools:compiler/dwz?expand=0&rev=26
This commit is contained in:
parent
9a6297a368
commit
05853d0d4a
98
dwz-fix-reference-from-pu-to-cu.patch
Normal file
98
dwz-fix-reference-from-pu-to-cu.patch
Normal file
@ -0,0 +1,98 @@
|
||||
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 <tdevries@suse.de>
|
||||
|
||||
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);
|
@ -1,3 +1,9 @@
|
||||
-------------------------------------------------------------------
|
||||
Fri Jan 17 06:30:58 UTC 2020 - Tom de Vries <tdevries@suse.com>
|
||||
|
||||
- Fix reference from compilation unit to partial unit [swo#25398].
|
||||
* dwz-fix-reference-from-pu-to-cu.patch
|
||||
|
||||
-------------------------------------------------------------------
|
||||
Thu Nov 28 12:56:34 UTC 2019 - Tom de Vries <tdevries@suse.com>
|
||||
|
||||
|
4
dwz.spec
4
dwz.spec
@ -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 @@ Patch1: dwz-update-version-copyright-message.patch
|
||||
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 @@ This package contains the testsuite results from DWZ.
|
||||
%patch2 -p1
|
||||
%patch3 -p1
|
||||
%patch4 -p1
|
||||
%patch5 -p1
|
||||
|
||||
%build
|
||||
make %{?_smp_mflags} CFLAGS="%{optflags}"
|
||||
|
Loading…
Reference in New Issue
Block a user