Accepting request 875421 from devel:tools:compiler

OBS-URL: https://build.opensuse.org/request/show/875421
OBS-URL: https://build.opensuse.org/package/show/openSUSE:Factory/dwz?expand=0&rev=15
This commit is contained in:
Dominique Leuenberger 2021-03-10 07:47:41 +00:00 committed by Git OBS Bridge
commit b4b91d3538
22 changed files with 564 additions and 1258 deletions

View File

@ -1,3 +0,0 @@
version https://git-lfs.github.com/spec/v1
oid sha256:8da2495d666ba94c1d9b0eca0799e32fc4553d5cbcc8eadfe90d7ca48cf4f5b0
size 113616

3
dwz-0.14~rc1.tar.xz Normal file
View File

@ -0,0 +1,3 @@
version https://git-lfs.github.com/spec/v1
oid sha256:370e7c0c09fc68e12fcff237a76b9eb3553833cbeeec6ae12e6c12f41eb9e289
size 146372

View File

@ -0,0 +1,28 @@
Add assert checking that CU is not referenced from PU
One of the invariants of dwz is that references from a newly created PU can
only reference other PUs.
Add an assert that checks this.
2021-02-25 Tom de Vries <tdevries@suse.de>
* dwz.c (write_die): Add assert.
---
dwz.c | 2 ++
1 file changed, 2 insertions(+)
diff --git a/dwz.c b/dwz.c
index 89cf8d1..887bf24 100644
--- a/dwz.c
+++ b/dwz.c
@@ -12572,6 +12572,8 @@ write_die (unsigned char *ptr, dw_cu_ref cu, dw_die_ref die,
{
dw_cu_ref refdcu = die_cu (refd);
value = refd->u.p2.die_new_offset;
+ assert (IMPLIES (cu->cu_kind == CU_PU,
+ die_cu (refd)->cu_kind == CU_PU));
assert (value && refdcu->cu_kind != CU_ALT);
if (t->attr[j].form == DW_FORM_ref_addr)
{

View File

@ -0,0 +1,64 @@
Call reorder_dups ASAP
Currently, we call reorder_dups just before partial unit creation, and only for
DIEs that will be copied.
This approach causes a problem with reachable DIE propagation (which is done
in partition_dups after phase 1): when a dup-chain that needs to be reordered
(starts with ODR_DECL but also contains ODR_DEF) is marked as reachable during
this propagation, propagation will stop at the ODR_DECL, while it should
continue at the first ODR_DEF instead.
Fix this by calling reorder_dups ASAP, just after computing the partitions.
The problem can be detected using this assert:
...
@@ -12563,6 +12563,8 @@ write_die
{
dw_cu_ref refdcu = die_cu (refd);
value = refd->u.p2.die_new_offset;
+ assert (IMPLIES (cu->cu_kind == CU_PU,
+ die_cu (refd)->cu_kind == CU_PU));
assert (value && refdcu->cu_kind != CU_ALT);
if (t->attr[j].form == DW_FORM_ref_addr)
{
...
2020-01-25 Tom de Vries <tdevries@suse.de>
PR dwz/25424
* dwz.c (partition_dups_1): Move calling of reorder_dups ...
(partition_dups): ... here.
---
dwz.c | 10 +++-------
1 file changed, 3 insertions(+), 7 deletions(-)
diff --git a/dwz.c b/dwz.c
index f435428..9172011 100644
--- a/dwz.c
+++ b/dwz.c
@@ -8134,13 +8134,6 @@ partition_dups_1 (dw_die_ref *arr, size_t nr_partitions, size_t *partitions,
&& (ignore_size || orig_size > new_size));
if (force)
{
- if (odr_active_p && odr_mode != ODR_BASIC)
- for (k = i; k < j; k++)
- {
- if (second_phase && !arr[k]->die_ref_seen)
- continue;
- arr[k] = reorder_dups (arr[k]);
- }
dw_die_ref die, *diep;
dw_cu_ref refcu = die_cu (arr[i]);
dw_cu_ref partial_cu = pool_alloc (dw_cu, sizeof (struct dw_cu));
@@ -8474,6 +8467,9 @@ partition_dups (void)
if (stats_p)
stats->part_cnt += nr_partitions;
+ if (odr_active_p && odr_mode != ODR_BASIC)
+ for (i = 0; i < vec_size; ++i)
+ arr[i] = reorder_dups (arr[i]);
if (partition_dups_1 (arr, nr_partitions, partitions, &first_partial_cu,
&last_partial_cu, false))
{

View File

@ -0,0 +1,32 @@
Document experimental status of odr
Add documentation of the experimental status of the odr optimization in dwz.1.
2021-02-25 Tom de Vries <tdevries@suse.de>
PR dwz/27401
* dwz.1: Document experimental status of odr.
---
dwz.1 | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/dwz.1 b/dwz.1
index 32df953..63c50d5 100644
--- a/dwz.1
+++ b/dwz.1
@@ -112,11 +112,13 @@ corresponding forms, instead of the GNU extension \fI.gnu_debugaltlink\fR
and corresponding forms.
.TP
.B \-\-odr / \-\-no-odr
+.B Experimental.
Enable/disable One-Definition-Rule optimization for C++ compilation units.
This optimization causes struct/union/class DIEs with the same name to be
considered equal. This has the effect that DIEs referring to distinct DIEs
representing the same type (like f.i. pointer type DIEs) are considered equal,
-and may be deduplicated.
+and may be deduplicated. The status of this optimization is experimental.
+It's disabled in low-mem mode.
Enabled by default.
.TP
.B \-\-odr-mode=<basic|link>

View File

@ -0,0 +1,44 @@
Enable odr by default
This reverts commit d49096d "[odr] Disable --odr by default".
---
dwz.1 | 2 +-
dwz.c | 4 ++--
2 files changed, 3 insertions(+), 3 deletions(-)
diff --git a/dwz.1 b/dwz.1
index e9117b2..32df953 100644
--- a/dwz.1
+++ b/dwz.1
@@ -117,7 +117,7 @@ This optimization causes struct/union/class DIEs with the same name to be
considered equal. This has the effect that DIEs referring to distinct DIEs
representing the same type (like f.i. pointer type DIEs) are considered equal,
and may be deduplicated.
-Disabled by default.
+Enabled by default.
.TP
.B \-\-odr-mode=<basic|link>
Set the One-Definition-Rule optimization aggressiveness: basic or link.
diff --git a/dwz.c b/dwz.c
index 887bf24..3342aba 100644
--- a/dwz.c
+++ b/dwz.c
@@ -230,7 +230,7 @@ enum die_count_methods
};
static enum die_count_methods die_count_method = estimate;
-int odr = 0;
+int odr = 1;
enum odr_mode { ODR_BASIC, ODR_LINK };
enum odr_mode odr_mode = ODR_LINK;
int odr_mode_parsed = 0;
@@ -16283,7 +16283,7 @@ static struct option_help dwz_common_options_help[] =
"Don't optimize files larger than this limit." },
{ NULL, "odr", NULL, NULL,
NULL },
- { NULL, "no-odr", NULL, "Disabled",
+ { NULL, "no-odr", NULL, "Enabled",
"Enable/disable one definition rule optimization." },
{ NULL, "odr-mode", "<basic|link>", "link",
"Set aggressiveness level of one definition rule optimization." },

View File

@ -1,138 +0,0 @@
Fix assertion 'off == cu_size' in recompute_abbrevs
[ Backport of master commit 331eabd. ]
With an executable from PR25024, we manage to reproduce PR24764:
...
$ dwz -l0 clang-offload-bundler-10.0.0-0.20190817snap5.fc30.x86_64.debug
dwz: dwz.c:9920: recompute_abbrevs: Assertion `off == cu_size' failed.
Aborted (core dumped)
...
The problem is that the cu_size as computed during recompute_abbrevs is not
the same as was computed before during compute_abbrevs.
I tracked down the first DIE in the CU that has a different size, at 0xdf615:
...
<5><df615>: Abbrev Number: 65 (DW_TAG_formal_parameter)
<df616> DW_AT_type : <0xe33be>
<df618> DW_AT_artificial : 1
...
Using a debug patch, we can track the size of the DIE during compute_abbrevs:
...
init_new_die_offsets: intracusize: 2
init_new_die_offsets: start die_size: 0
init_new_die_offsets: add DIE code size to die_size: 1
init_new_die_offsets: add nr_refs * intracusize to die_size: 3
update_new_die_offsets: die_size: 3
update_new_die_offsets: die_size: 3
finalize_new_die_offsets: die_size: 3
...
and recompute_abbrevs:
...
init_new_die_offsets: intracusize: 3
init_new_die_offsets: start die_size: 0
init_new_die_offsets: add DIE code size to die_size: 1
init_new_die_offsets: add nr_refs * intracusize to die_size: 4
update_new_die_offsets: die_size: 4
update_new_die_offsets: die_size: 4
update_new_die_offsets: die_size: 4
finalize_new_die_offsets: die_size: 4
...
The difference starts in init_new_die_offsets, when adding intracusize, which
is different for compute_abbrevs and recompute_abbrevs (2 vs. 3).
The code in recompute_abbrevs that calculates intracusize for the relevant
init_new_die_offsets call is:
...
/* Need to be conservatively high estimate, as update_new_die_offsets
relies on the offsets always decreasing. cu_size at this point is
the size we will end up with in the end, but if cu_size is
sufficiently close (from bottom) to some uleb128 boundary (say
16384), init_new_die_offsets might return off above that boundary
and then update_new_die_offsets might fail its assertions on
reference to DIEs that crossed the uleb128 boundary. */
intracusize = size_of_uleb128 (2 * cu_size);
off = init_new_die_offsets (cu->cu_die, headersz, intracusize);
...
where the '2 * cu_size' is the result of commit d16aa5e "Fix up
recompute_abbrevs if cu_size is close below an uleb128 boundary and
init_new_die_offsets would return offset above that uleb128 boundary":
...
- intracusize = size_of_uleb128 (cu_size);
+ intracusize = size_of_uleb128 (2 * cu_size);
...
Reverting commit d16aa5e gets us an intracusize of 2 in recompute_abbrevs, and
fixes the assert. However, doing so reintroduces the assertion that was fixed
by the commit (at least, provided commit a4668e1 "Fix assertion failure in
create_import_tree" is also reverted):
...
$ dwz -l0 inkview.debug
dwz: dwz.c:8527: update_new_die_offsets: Assertion \
`die->u.p2.die_intracu_udata_size >= intracu_udata_size' failed.
Aborted (core dumped)
...
Fix the 'off == cu_size' assert (without introducing the regression for
inkview.debug) by:
- saving the intracusize used for the call to init_new_die_offsets in
compute_abbrevs, and
- reusing the saved intracusize for the call to init_new_die_offsets in
recompute_abbrevs.
Also tested with clang and CheckerOptionHandlingAnalyzerPlugin.so, for which
this PR also triggered.
2019-11-27 Tom de Vries <tdevries@suse.de>
PR dwz/24764
* dwz.c (struct dw_cu): Add initial_intracusize field.
(compute_abbrevs): Initalize initial_intracusize.
(recompute_abbrevs): Use initial_intracusize.
---
dwz.c | 13 +++++--------
1 file changed, 5 insertions(+), 8 deletions(-)
diff --git a/dwz.c b/dwz.c
index 7c7b401..928fefa 100644
--- a/dwz.c
+++ b/dwz.c
@@ -674,6 +674,9 @@ struct dw_cu
unsigned int cu_chunk;
/* Form chosen for intra-cu references. */
enum dwarf_form cu_intracu_form;
+ /* Intracusize argument to init_new_die_offsets. Set in compute_abbrevs,
+ used in recompute_abbrevs. */
+ unsigned int initial_intracusize;
};
/* Internal representation of a debugging information entry (DIE).
@@ -8405,6 +8408,7 @@ compute_abbrevs (DSO *dso)
intracusize = i;
}
while (1);
+ cu->initial_intracusize = intracusize;
off = init_new_die_offsets (cu->cu_die, headersz, intracusize);
do
{
@@ -9555,14 +9559,7 @@ recompute_abbrevs (dw_cu_ref cu, unsigned int cu_size)
}
else
{
- /* Need to be conservatively high estimate, as update_new_die_offsets
- relies on the offsets always decreasing. cu_size at this point is
- the size we will end up with in the end, but if cu_size is
- sufficiently close (from bottom) to some uleb128 boundary (say
- 16384), init_new_die_offsets might return off above that boundary
- and then update_new_die_offsets might fail its assertions on
- reference to DIEs that crossed the uleb128 boundary. */
- intracusize = size_of_uleb128 (2 * cu_size);
+ intracusize = cu->initial_intracusize;
off = init_new_die_offsets (cu->cu_die, headersz, intracusize);
do

View File

@ -1,485 +0,0 @@
- Add iterators.h
- Fix die_no_multifile propagation
------------------------------------------------------------
Add iterators.h
[ Backport of master commit 61c225a. ]
Add FOREACH_* iterators that iterate over CUs.
Add two iterator functions next_die and next_toplevel die. Using these
functions, we can describe actions for all (toplevel) DIEs without having to
write a recursive function.
Add FOREACH_* iterators that iterate over DIEs using these functions.
Add FOREACH_* iterators that combine the previous two kinds of FOREACH_*
iterators to iterate over CUs and their DIEs.
2019-11-04 Tom de Vries <tdevries@suse.de>
* iterators.h: New file.
* dwz.c: Include iterators.h.
------------------------------------------------------------
Fix die_no_multifile propagation
[ Backport of master commit 172afd9. ]
I. Terminology
A pseudo-reference from DIE A to DIE B is a reference related to an attribute
of DIE A of class exprloc (or by extension, loclistptr) containing a DWARF
operator (DW_OP_GNU_variable_value, DW_OP_GNU_implicit_pointer,
DW_OP_call_ref) that contains a reference to DIE B.
This in contrast to a regular reference, related to an attribute of
reference class.
II. Assert
When running the test-case from PR25109, we run into an assert:
...
$ cp StartGui.so 1
$ cp 1 2
$ dwz -m 3 1 2
dwz: dwz.c:9310: write_die: \
Assertion `value && refdcu->cu_kind != CU_ALT' failed.
Aborted (core dumped)
...
The assert is a regression due to commit 5f3ba3a "Mark
DW_OP_GNU_variable_value-referenced DIEs with die_no_multifile".
III. Revisit commit 5f3ba3a
To reiterate the problem fixed by that commit, the issue is that for DIEs
A and B with a pseudo-reference from A to B:
...
(A) --pr--> (B)
...
we have the situation that B ends up in the multifile, and A not, and we end
up in finalize_multifile trying to rewrite the pseudo-reference from A to the
copy of B in the multifile.
It's good to note that for a regular reference, this wouldn't be a problem.
We would simply rewrite the reference in A using DW_FORM_GNU_ref_alt. But for
the DWARF operators used in pseudo-references, that's not an option because
there are no _alt variants.
The committed fix is to forbid B to move to the multifile, by setting
die_no_multifile to 1.
[ Alternatively, it might be possible to fix this by still allowing B to be
copied to the multifile, and when in finalize_multifile, not rewrite
the pseudo-reference and keep a copy of B in addition to the one in the
multifile. ]
[ It might be possible for both A and B to move to the multifile. But the
current implementation makes decisions to move individual DIEs to the
multifile or not, and doesn't consider clusters of DIEs, so we have to take a
conservative approach. ]
IV. Assert analysis
The situation when we run into the assert is as follows:
- we have two duplicate chains: {A, B} and {C, D, E, F}
- each duplicate chain has a representant: A' and C'
- there's a pseudo-ref from Z to C
Schematically this looks like this:
...
(A') --------d-------> (A) --------d-------> (B)
| | |
r r r
| | |
v v v
(C') --d--> (C) --d--> (D) --d--> (E) --d--> (F)
^
|
pr
|
(Z)
...
The assert happens in write_multifile, when we're trying to write out A' to the
aggregate file (the collection of debug sections in temporary files), due
to die_no_multifile == 0, and finding out that we can't rewrite the reference
from A' to C' because C' is not written out to the candidate multifile, due to
die_no_multifile == 1. And C' has die_no_multifile == 1 due to C having
die_no_multifile == 1, which is due to the fix from commit 5f3ba3a.
The problem can be formulated as insufficient propagation of the
die_no_multifile property. That is: the property on C did propagate to C',
as it should, but failed to propagate to A'.
V. Property die_no_multifile propagation
The die_no_multifile property propagation is done in 4 phases:
1. The DIEs are seeded with the property, and the property is propagated
upward towards the toplevel DIEs.
2. The property is propagated backward over regular references.
3. The property is propagated from the duplicate chain to the representant.
4. The property is propagated from the representant back into the duplicate
chain, but in an inverse manner: If the property on the representant is false,
the property is set to true on the duplicate chain. Which is a way of saying:
if we are going to write the representant to the multifile, there's no need to
write any of the members of the duplicate chain to the multifile.
In a way the propagation proper is phases 1-3, and phase 4 is a seperate thing
that we might call inverse propagation, and which AFAICT is not relevant to the
problem at hand.
Implementationwise, phase 1 takes place during checksum_die, phase 2 during
checksum_ref_die, and phase 3 and 4 during check_multifile.
VI. Propagation analysis
Now we can break down how propagation is done for the situation described at
IV:
- During phase 1, C is seeded with the property, on account of the
pseudo-reference Z -> C.
- During phase 2, the property state is propagated back from D to A and from F
to B, but since the property is false on D and F, that doesn't change
anything.
- During phase 3, the property is propagated from C to C'.
What seems to be missing is a propagation before phase 2 from C to fellow
duplicate chain members D, E and F. [ However, in order to do this
propagation, we need the duplicate chains, which are only available after
we're done with checksum_ref_die, which is where phase 2 is done. ]
VII. Program invariant
So why did the propagation work up until now? The answer is that there's an
AFAIK undocumented program invariant that states that if a DIE has the
property set, all fellow members in the duplicate chain will also have it set
(even before the duplicate chains are known). This invariant held right up
until commit 5f3ba3a broke it.
VIII. Fix
The fix for the assert implemented in this patch, is to add a
propagate_multifile function called before phase 3, which adds the missing
propagation. It consists of two parts:
- propagate_multifile_duplicate_chain
- propagate_multifile_refs_backward
where the first adds what was described as missing in VI, and the second is a
copy of phase 2 that doesn't piggyback on checksum_ref_die.
The two are called iteratively until fixed point is reached.
2019-11-02 Tom de Vries <tdevries@suse.de>
PR dwz/25109
* dwz.c (propagate_multifile_duplicate_chain):
(propagate_multifile_refs_backward, propagate_multifile): New function.
(write_multifile): Call propagate_multifile.
------------------------------------------------------------
diff --git a/dwz.c b/dwz.c
index 727314f..308957e 100644
--- a/dwz.c
+++ b/dwz.c
@@ -794,6 +794,8 @@ struct dw_die
dw_die_ref die_nextdup;
};
+#include "iterators.h"
+
/* Return CU structure pointer for a DIE. In order to save memory,
individual DIEs don't have a dw_cu_ref field, and the pointer can
be only found by overriding the die_parent pointer in a
diff --git a/iterators.h b/iterators.h
new file mode 100644
index 0000000..8672ccf
--- /dev/null
+++ b/iterators.h
@@ -0,0 +1,126 @@
+/* Various iterators.
+
+ Copyright (C) 2019 SUSE LLC.
+
+ This program 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 2, or (at your option)
+ any later version.
+
+ This program 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; see the file COPYING. If not, write to
+ the Free Software Foundation, 51 Franklin Street - Fifth Floor,
+ Boston, MA 02110-1301, USA. */
+
+
+/* CU iterators. */
+
+#define FOREACH_CU(CU) \
+ for (CU = first_cu; CU; CU = CU->cu_next)
+
+#define FOREACH_CU_PU(CU) \
+ for (CU = first_cu; CU && CU->cu_kind == CU_PU; CU = CU->cu_next)
+
+#define FOREACH_CU_NORMAL(CU) \
+ for (CU = first_cu; CU && CU->cu_kind != CU_TYPES; CU = CU->cu_next) \
+ if (CU->cu_kind == CU_NORMAL)
+
+#define FOREACH_CU_TYPES(CU) \
+ for (CU = first_cu; CU; CU = CU->cu_next) \
+ if (CU->cu_kind == CU_TYPES) \
+
+/* Function that describes a depth-first traversal path visiting all dies. */
+
+static inline dw_die_ref FORCE_INLINE
+next_die (dw_die_ref die)
+{
+ if (die->die_child != NULL)
+ return die->die_child;
+
+ while (1)
+ {
+ if (die->die_sib != NULL)
+ return die->die_sib;
+
+ if (die->die_root)
+ return NULL;
+
+ die = die->die_parent;
+ }
+}
+
+/* Function that describes a depth-first traversal path visiting all toplevel
+ dies. */
+
+static inline dw_die_ref FORCE_INLINE
+next_toplevel_die (dw_die_ref die)
+{
+ if (die->die_child != NULL && die->die_child->die_toplevel)
+ return die->die_child;
+
+ while (1)
+ {
+ if (die->die_sib != NULL && die->die_sib->die_toplevel)
+ return die->die_sib;
+
+ if (die->die_root)
+ return NULL;
+
+ die = die->die_parent;
+ }
+}
+
+/* DIE_IN_CU iterators. */
+
+#define FOREACH_DIE_IN_CU(DIE, CU) \
+ for (DIE = CU->cu_die; DIE; DIE = next_die (DIE))
+
+#define FOREACH_TOPLEVEL_DIE_IN_CU(DIE, CU) \
+ for (DIE = CU->cu_die; DIE; DIE = next_toplevel_die (DIE))
+
+#define FOREACH_LOW_TOPLEVEL_DIE_IN_CU(DIE, CU) \
+ FOREACH_TOPLEVEL_DIE_IN_CU (DIE, CU) \
+ if (!(die->die_root || die->die_named_namespace))
+
+/* DIE iterators. */
+
+#define FOREACH_DIE(CU, DIE) \
+ FOREACH_CU (CU) \
+ FOREACH_DIE_IN_CU (DIE, CU)
+
+#define FOREACH_TOPLEVEL_DIE(CU, DIE) \
+ FOREACH_CU (CU) \
+ FOREACH_TOPLEVEL_DIE_IN_CU (DIE, CU)
+
+#define FOREACH_LOW_TOPLEVEL_DIE(CU, DIE) \
+ FOREACH_CU (CU) \
+ FOREACH_LOW_TOPLEVEL_DIE_IN_CU (DIE, CU)
+
+#define FOREACH_CU_PU_TOPLEVEL_DIE(CU, DIE) \
+ FOREACH_CU_PU (CU) \
+ FOREACH_TOPLEVEL_DIE_IN_CU (DIE, CU)
+
+#define FOREACH_CU_NORMAL_TOPLEVEL_DIE(CU, DIE) \
+ FOREACH_CU_NORMAL (CU) \
+ FOREACH_TOPLEVEL_DIE_IN_CU (DIE, CU)
+
+#define FOREACH_CU_TYPES_TOPLEVEL_DIE(CU, DIE) \
+ FOREACH_CU_TYPES (CU) \
+ FOREACH_TOPLEVEL_DIE_IN_CU (DIE, CU)
+
+#define FOREACH_CU_PU_LOW_TOPLEVEL_DIE(CU, DIE) \
+ FOREACH_CU_PU (CU) \
+ FOREACH_LOW_TOPLEVEL_DIE_IN_CU (DIE, CU)
+
+#define FOREACH_CU_NORMAL_LOW_TOPLEVEL_DIE(CU, DIE) \
+ FOREACH_CU_NORMAL (CU) \
+ FOREACH_LOW_TOPLEVEL_DIE_IN_CU (DIE, CU)
+
+#define FOREACH_CU_TYPES_LOW_TOPLEVEL_DIE(CU, DIE) \
+ FOREACH_CU_TYPES (CU) \
+ FOREACH_LOW_TOPLEVEL_DIE_IN_CU (DIE, CU)
diff --git a/dwz.c b/dwz.c
index 308957e..7c7b401 100644
--- a/dwz.c
+++ b/dwz.c
@@ -11007,6 +11007,149 @@ cleanup (void)
max_line_id = 0;
}
+/* Propagate the die_no_multifile property along the duplicate chain of which
+ DIE is a member. If the property was changed on any die, set *CHANGED to
+ true. */
+static void
+propagate_multifile_duplicate_chain (dw_die_ref die, bool *changed)
+{
+ dw_die_ref dup = first_dup (die);
+ if (!dup)
+ return;
+
+ while (dup && dup->die_offset == -1U)
+ dup = dup->die_nextdup;
+ if (dup != die)
+ return;
+
+ bool any_no_multifile = false;
+ bool any_multifile = false;
+ bool prop_needed = false;
+ dw_die_ref d;
+ for (d = dup; d && !prop_needed; d = d->die_nextdup)
+ {
+ if (d->die_no_multifile)
+ any_no_multifile = true;
+ else
+ any_multifile = true;
+ prop_needed = any_no_multifile && any_multifile;
+ }
+ if (!prop_needed)
+ return;
+
+ *changed = true;
+
+ for (d = dup; d; d = d->die_nextdup)
+ d->die_no_multifile = 1;
+}
+
+/* Propagate the die_no_multifile property backwards along the outgoing
+ references of DIE, which is a member of CU and of the subtree of lower
+ toplevel die TOP_DIE. If the property was changed on any die, set *CHANGED
+ to true. */
+static void
+propagate_multifile_refs_backward (dw_cu_ref cu, dw_die_ref top_die,
+ dw_die_ref die, bool *changed)
+{
+ struct abbrev_tag *t = die->die_abbrev;
+ unsigned int i;
+ unsigned char *ptr;
+ dw_die_ref child;
+
+ if (die->die_offset == -1U)
+ return;
+
+ ptr = debug_sections[DEBUG_INFO].data + die->die_offset;
+ read_uleb128 (ptr);
+ for (i = 0; i < t->nattr; ++i)
+ {
+ uint32_t form = t->attr[i].form;
+ uint64_t value;
+ dw_die_ref ref, reft;
+
+ while (form == DW_FORM_indirect)
+ form = read_uleb128 (ptr);
+
+ switch (form)
+ {
+ case DW_FORM_ref_addr:
+ value = read_size (ptr, cu->cu_version == 2 ? ptr_size : 4);
+ ptr += cu->cu_version == 2 ? ptr_size : 4;
+ ref = off_htab_lookup (cu, value);
+ goto finish_ref;
+ break;
+ case DW_FORM_ref_udata:
+ case DW_FORM_ref1:
+ case DW_FORM_ref2:
+ case DW_FORM_ref4:
+ case DW_FORM_ref8:
+ switch (form)
+ {
+ case DW_FORM_ref_udata: value = read_uleb128 (ptr); break;
+ case DW_FORM_ref1: value = read_8 (ptr); break;
+ case DW_FORM_ref2: value = read_16 (ptr); break;
+ case DW_FORM_ref4: value = read_32 (ptr); break;
+ case DW_FORM_ref8: value = read_64 (ptr); break;
+ default: abort ();
+ }
+ if (t->attr[i].attr == DW_AT_sibling)
+ break;
+ ref = off_htab_lookup (cu, cu->cu_offset + value);
+ finish_ref:
+ reft = ref;
+ while (!reft->die_root
+ && reft->die_parent->die_tag != DW_TAG_compile_unit
+ && reft->die_parent->die_tag != DW_TAG_partial_unit
+ && !reft->die_parent->die_named_namespace)
+ reft = reft->die_parent;
+ if (reft->die_root)
+ ;
+ else if (reft->die_ck_state == CK_KNOWN
+ && !top_die->die_no_multifile && reft->die_no_multifile)
+ {
+ top_die->die_no_multifile = 1;
+ *changed = true;
+ }
+ break;
+ default:
+ ptr = skip_attr_no_dw_form_indirect (cu, form, ptr);
+ }
+ }
+
+ for (child = die->die_child; child; child = child->die_sib)
+ propagate_multifile_refs_backward (cu, top_die, child, changed);
+}
+
+/* Do propagation of the die_no_multifile property that was not covered in
+ checksum_die and checksum_ref_die. */
+static void
+propagate_multifile (void)
+{
+ bool changed;
+ dw_cu_ref cu;
+ dw_die_ref die;
+
+ changed = false;
+
+ FOREACH_CU_NORMAL_LOW_TOPLEVEL_DIE (cu, die)
+ propagate_multifile_duplicate_chain (die, &changed);
+
+ if (!changed)
+ return;
+
+ do
+ {
+ changed = false;
+
+ FOREACH_CU_NORMAL_LOW_TOPLEVEL_DIE (cu, die)
+ propagate_multifile_refs_backward (cu, die, die, &changed);
+
+ FOREACH_CU_NORMAL_LOW_TOPLEVEL_DIE (cu, die)
+ propagate_multifile_duplicate_chain (die, &changed);
+ }
+ while (changed);
+}
+
/* Returns true if DIE contains any toplevel children that can be
potentially shared between different executables or shared libraries. */
static bool
@@ -11347,6 +11490,7 @@ write_multifile (DSO *dso)
debug_sections[i].new_data = NULL;
debug_sections[i].new_size = debug_sections[i].size;
}
+ propagate_multifile ();
for (cu = first_cu; cu && cu->cu_kind != CU_TYPES; cu = cu->cu_next)
{
cu->u1.cu_new_abbrev_owner = NULL;

View File

@ -1,55 +0,0 @@
Fix 'refd != NULL' assertion in write_die
[ Backport of master commits 6959430 and 7cc8aae. ]
When running dwz on a file that contains invalid DW_FORM_ref_addr attributes
(which has been observed to be generated by a google go compiler) we run
either into an assert:
...
$ dwz multidictionary
dwz: dwz.c:9461: write_die: Assertion `refd != NULL' failed.
Aborted (core dumped)
...
or a segmentation fault in case of low-mem mode:
...
$ dwz -l0 multidictionary
Segmentation fault (core dumped)
...
Fix this by erroring out instead:
...
$ dwz multidictionary
dwz: Couldn't find DIE at DW_FORM_ref_addr offset 0x97
...
2019-02-05 Tom de Vries <tdevries@suse.de>
PR dwz/24169
* dwz.c (write_die): Error out on invalid DW_FORM_ref_addr.
---
dwz.c | 4 ++++
1 file changed, 4 insertions(+)
diff --git a/dwz.c b/dwz.c
index 928fefa..c7db337 100644
--- a/dwz.c
+++ b/dwz.c
@@ -28,6 +28,7 @@
#include <stdbool.h>
#include <stddef.h>
#include <stdint.h>
+#include <inttypes.h>
#include <stdlib.h>
#include <unistd.h>
#include <sys/mman.h>
@@ -9124,6 +9125,9 @@ write_die (unsigned char *ptr, dw_cu_ref cu, dw_die_ref die,
? ptr_size : 4);
inptr += refcu->cu_version == 2 ? ptr_size : 4;
refd = off_htab_lookup (NULL, value);
+ if (refd == NULL || refd->die_tag == 0)
+ error (1, 0, "Couldn't find DIE at DW_FORM_ref_addr offset"
+ " 0x%" PRIx64, value);
assert (refd != NULL);
refdt = refd;
while (refdt->die_toplevel == 0)

View File

@ -1,98 +0,0 @@
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);

View File

@ -0,0 +1,69 @@
Fix reference of PU to CU for odr
When compiling dwz with the assert listed in the commit message for
"Call reorder_dups ASAP", and using test-case cc1.dwz-processed like so, we
run into:
...
$ dwz cc1.dwz-processed -o 1 -lnone --odr
dwz: dwz.c:12567: write_die: Assertion \
`IMPLIES (cu->cu_kind == CU_PU, die_cu (refd)->cu_kind == CU_PU)' failed.
Aborted (core dumped)
...
The assert is related to this duplicate chain:
...
28dd83f O b500801d 621b6872 pointer_type \
(type: 28dd72f die_struct structure_type)
2903769 O b500801d 621b6872 pointer_type \
(type: 28dd72f die_struct structure_type)
...
which contains two DIEs that are both in the same CU:
...
<0><28d281f>: Abbrev Number: 200 (DW_TAG_compile_unit)
...
<1><28dd72f>: Abbrev Number: 35 (DW_TAG_structure_type)
<28dd730> DW_AT_name : (indirect string, offset: 0x1b2ca6): die_struct
<28dd734> DW_AT_byte_size : 80
<28dd735> DW_AT_decl_file : 87
<28dd736> DW_AT_decl_line : 3069
<28dd738> DW_AT_decl_column : 63
<28dd739> DW_AT_sibling : <0x28dd83b>
<1><28dd83f>: Abbrev Number: 9 (DW_TAG_pointer_type)
<28dd840> DW_AT_byte_size : 8
<28dd841> DW_AT_type : <0x28dd72f>
...
<1><2903769>: Abbrev Number: 9 (DW_TAG_pointer_type)
<290376a> DW_AT_byte_size : 8
<290376b> DW_AT_type : <0x28dd72f>
...
<0><2911617>: Abbrev Number: 177 (DW_TAG_compile_unit)
...
The dup chain is forced to a partial unit, but the die_struct DIE is not,
because it's not part of a duplicate chain, and it's not marked as a
singleton. Fix this by marking the die_struct DIE as singleton.
2021-02-25 Tom de Vries <tdevries@suse.de>
PR dwz/27464
* dwz.c (partition_dups): Call mark_singletons if
cnt_ref_cus (die) == 1.
---
dwz.c | 3 +++
1 file changed, 3 insertions(+)
diff --git a/dwz.c b/dwz.c
index 9172011..89cf8d1 100644
--- a/dwz.c
+++ b/dwz.c
@@ -8417,6 +8417,9 @@ partition_dups (void)
if (s)
mark_singletons (die_cu (s), s, s, &ob2);
}
+ else if (cnt_ref_cus (die) == 1)
+ mark_singletons (die_cu (die), die, die, &ob2);
+
arr = (dw_die_ref *) obstack_base (&ob2);
}

View File

@ -1,55 +0,0 @@
Fix segfault in die_cu
[ Backport of master commit e2c440e. ]
When running dwz in normal mode, we get an error:
...
$ dwz clang-offload-bundler-10.debug -lnone
dwz: clang-offload-bundler-10.debug: Couldn't find DIE referenced by \
DW_OP_GNU_implicit_pointer
...
but when forcing low-mem mode, we get a segfault:
...
$ dwz clang-offload-bundler-10.debug -l0
Segmentation fault (core dumped)
...
In normal mode, we hit the error here:
...
ref = off_htab_lookup (NULL, addr);
if (ref == NULL)
{
error (0, 0, "%s: Couldn't find DIE referenced by %s",
dso->filename, get_DW_OP_str (op));
...
but for low-mem mode, this doesn't trigger, because we find the dummy DIE that
has been added by read_exprloc_low_mem_phase1.
Fix this by testing for the dummy DIE in the error condition:
...
- if (ref == NULL)
+ if (ref == NULL || (unlikely (low_mem) && ref->die_tag == 0))
...
2020-01-24 Tom de Vries <tdevries@suse.de>
PR dwz/25456
* dwz.c (read_exprloc): Test for dummy DIE in error condition.
---
dwz.c | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/dwz.c b/dwz.c
index 298bca1..44b5ba3 100644
--- a/dwz.c
+++ b/dwz.c
@@ -1597,7 +1597,7 @@ read_exprloc (DSO *dso, dw_die_ref die, unsigned char *ptr, size_t len,
else
ptr += 4;
ref = off_htab_lookup (NULL, addr);
- if (ref == NULL)
+ if (ref == NULL || (unlikely (low_mem) && ref->die_tag == 0))
{
error (0, 0, "%s: Couldn't find DIE referenced by %s",
dso->filename, get_DW_OP_str (op));

View File

@ -0,0 +1,165 @@
Precompute partitions
Currently, we calculate the duplicate chain partitions in partition_dups_1.
This is done twice, once for phase 1 and once for phase 2.
Instead, calculate the partitions once in partition_dups, and use those for
both calls to partition_dups_1.
Performance tested on cc1. This causes a small performance regresssion:
...
user:
series: 5140 5100 5120 5130 5150 5160 5160 5180 5170 5130 \
5180 5160 5090 5230 5140 5140 5210 5100 5170 5130
mean: 5149.50 (100%)
stddev: 35.46
series: 5120 5190 5230 5190 5200 5160 5170 5210 5270 5180 \
5270 5240 5200 5200 5200 5170 5150 5220 5180 5140
mean: 5194.50 (100.87%)
stddev: 39.13
...
There's no significant increase of memory usage:
...
mem:
series: 1260512 1260456 1260492 1260368 1260608 1260268 1260656 1260488 \
1260420 1260332 1260464 1260488 1260536 1260340 1260352 1260492 \
1260268 1260276 1260316 1260316
mean: 1260422.40 (100%)
stddev: 113.73
series: 1260456 1260296 1260244 1260360 1260584 1260344 1260548 1260388 \
1260424 1260304 1260252 1260560 1260664 1260476 1260480 1260416 \
1260580 1260504 1260604 1260324
mean: 1260440.40 (100.00%)
...
We accept the small performance penalty because this patch is a prerequisite
for the PR25424 bug fix.
2021-02-25 Tom de Vries <tdevries@suse.de>
* dwz.c (calculate_partitions): New function, factored out of ...
(partition_dups_1): ... here. Drop vec_size parameter. Add
nr_partitions and partitions parameter. Iterate over partitions array.
(partition_dups): Call calculate_partitions. Update calls to
partition_dups_1.
---
dwz.c | 75 +++++++++++++++++++++++++++++++++++++++++++++++--------------------
1 file changed, 53 insertions(+), 22 deletions(-)
diff --git a/dwz.c b/dwz.c
index e71b3fa..f435428 100644
--- a/dwz.c
+++ b/dwz.c
@@ -7989,34 +7989,26 @@ cnt_ref_cus (dw_die_ref ref)
multiple CUs might be worthwhile to be moved into partial units,
construct those partial units. */
static bool
-partition_dups_1 (dw_die_ref *arr, size_t vec_size,
+partition_dups_1 (dw_die_ref *arr, size_t nr_partitions, size_t *partitions,
dw_cu_ref *first_partial_cu,
dw_cu_ref *last_partial_cu,
bool second_phase)
{
- size_t i, j;
+ size_t i, j, cnt;
bool ret = false;
- for (i = 0; i < vec_size; i = j)
+ size_t idx = 0;
+ for (idx = 0; idx < nr_partitions * 2; idx += 2)
{
+ i = partitions[idx];
+ cnt = partitions[idx + 1];
+ j = partitions[idx + 2];
+
+ if (arr[i]->die_dup != NULL)
+ continue;
+
dw_die_ref ref;
- size_t cnt = 0, size = 0, k, orig_size, new_size, namespaces = 0;
+ size_t size = 0, k, orig_size, new_size, namespaces = 0;
unsigned int force = 0;
- if (arr[i]->die_dup != NULL)
- {
- j = i + 1;
- continue;
- }
- for (j = i + 1; j < vec_size; j++)
- {
- size_t this_cnt;
- if (!same_ref_cus_p (arr[i], arr[j], &this_cnt))
- break;
- cnt = this_cnt;
- }
- if (stats_p && !second_phase)
- stats->part_cnt++;
- if (cnt == 0)
- cnt = cnt_ref_cus (arr[i]);
enum dwarf_source_language part_lang
= gen_cu_p ? partition_lang (arr[i]) : 0;
for (k = i; k < j; k++)
@@ -8289,6 +8281,36 @@ partition_dups_1 (dw_die_ref *arr, size_t vec_size,
return ret;
}
+/* Partition the duplicate chains in array ARR with size VEC_SIZE, and store
+ the partitions on obstack ob2, with for each partition two entries:
+ the start and the number of unique reffer CUs. */
+static void
+calculate_partitions (dw_die_ref *arr, size_t vec_size)
+{
+ size_t i, j;
+ for (i = 0; i < vec_size; i = j)
+ {
+ size_t cnt = 0;
+ for (j = i + 1; j < vec_size; j++)
+ {
+ size_t this_cnt;
+ if (!same_ref_cus_p (arr[i], arr[j], &this_cnt))
+ break;
+ cnt = this_cnt;
+ }
+ if (cnt == 0)
+ cnt = cnt_ref_cus (arr[i]);
+ obstack_grow (&ob2, &i, sizeof (size_t));
+ obstack_grow (&ob2, &cnt, sizeof (size_t));
+ }
+
+ /* Add element to mark end of partition list. This allows us to do
+ 'j = partitions[idx + 2]' for all partitions. */
+ obstack_grow (&ob2, &j, sizeof (size_t));
+ size_t zero = 0;
+ obstack_grow (&ob2, &zero, sizeof (size_t));
+}
+
static inline void FORCE_INLINE
reset_die_ref_seen (void)
{
@@ -8443,7 +8465,16 @@ partition_dups (void)
report_progress ();
fprintf (stderr, "partition_dups after qsort\n");
}
- if (partition_dups_1 (arr, vec_size, &first_partial_cu,
+
+ size_t *partitions = (size_t *) obstack_base (&ob2);
+ calculate_partitions (arr, vec_size);
+ size_t nr_partitions
+ = (obstack_object_size (&ob2) / sizeof (size_t)) / 2 - 1;
+ partitions = (size_t *) obstack_finish (&ob2);
+ if (stats_p)
+ stats->part_cnt += nr_partitions;
+
+ if (partition_dups_1 (arr, nr_partitions, partitions, &first_partial_cu,
&last_partial_cu, false))
{
for (i = 0; i < vec_size; i++)
@@ -8452,7 +8483,7 @@ partition_dups (void)
if (arr[i]->die_dup != NULL)
mark_refs (die_cu (arr[i]), arr[i], arr[i],
MARK_REFS_FOLLOW_DUPS);
- partition_dups_1 (arr, vec_size, &first_partial_cu,
+ partition_dups_1 (arr, nr_partitions, partitions, &first_partial_cu,
&last_partial_cu, true);
for (i = 0; i < vec_size; i++)
arr[i]->die_ref_seen = 0;

View File

@ -1,29 +0,0 @@
Adjust pr24468.sh test-case for readelf with =follow-links.
Newer binutils readelf have =follow-links which is automatically
enabled with -w. This shows not only the debuginfo of the main file
but also that of the alt file referenced. This causes the pr24468.sh
to see "too many" DW_TAG_partial_units (from both files) which then
doesn't matches the number of DW_AT_imports. The fix is simply to
use -wi instead of -w since we are only interested in the .debug_info
DIEs anyway.
* testsuite/dwz.tests/pr24468.sh: Use readelf -wi.
---
testsuite/dwz.tests/pr24468.sh | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/testsuite/dwz.tests/pr24468.sh b/testsuite/dwz.tests/pr24468.sh
index b03fdf9..4dac9a1 100644
--- a/testsuite/dwz.tests/pr24468.sh
+++ b/testsuite/dwz.tests/pr24468.sh
@@ -5,7 +5,7 @@ cp 1 2
dwz -m 3 1 2
-readelf -w 1 > READELF 2>/dev/null
+readelf -wi 1 > READELF 2>/dev/null
offsets=$(grep '(DW_TAG_partial_unit' READELF \
| awk '{print $1}' \

View File

@ -1,39 +0,0 @@
[testsuite] Detect when devel-ignore-size.sh is unsupported
In PR27115, a failure of devel-ignore-size.sh is reported.
The test-case:
- tries to transform an executable
- checks that it didn't transform
- retries using --devel-ignore-size
- check that it did transform
The reported failure is in the second step.
Fix this by marking the test unsupported if the second step fails.
2021-01-04 Tom de Vries <tdevries@suse.de>
PR dwz/27115
* testsuite/dwz.tests/devel-ignore-size.sh: If exec is transformed
without --devel-ignore-size, mark unsupported.
---
testsuite/dwz.tests/devel-ignore-size.sh | 4 +++-
1 file changed, 3 insertions(+), 1 deletion(-)
diff --git a/testsuite/dwz.tests/devel-ignore-size.sh b/testsuite/dwz.tests/devel-ignore-size.sh
index 5134043..78d28a2 100644
--- a/testsuite/dwz.tests/devel-ignore-size.sh
+++ b/testsuite/dwz.tests/devel-ignore-size.sh
@@ -12,7 +12,9 @@ cnt=$(readelf -wi 1 \
| grep '(DW_TAG_partial_unit' \
| wc -l)
-[ $cnt -eq 0 ]
+if [ $cnt -ne 0 ]; then
+ exit 77
+fi
cp $execs/min 1

View File

@ -1,50 +0,0 @@
[testsuite] Fix partial unit grepping in pr24468.sh
I'm running into:
...
FAIL: src/testsuite/dwz.tests/pr24468.sh
...
In more detail, we find the following offsets for partial units:
...
+ offsets='b
6b
da'
...
and then fail to find an import for the one at 6b:
...
++ grep -c 'DW_AT_import.*0x6b' READELF
++ true
+ imports=0
+ '[' 0 -gt 0 ']'
...
But there's actually no partial unit at 6b, the grep matches on a
DW_AT_import:
...
<6b> DW_AT_import : <0xb> [Abbrev Number: 17 (DW_TAG_partial_unit)]
...
Fix this by filtering out the DW_AT_import lines when grepping for partial
units.
2020-12-20 Tom de Vries <tdevries@suse.de>
* testsuite/dwz.tests/pr24468.sh: Fix partial unit grepping.
---
testsuite/dwz.tests/pr24468.sh | 1 +
1 file changed, 1 insertion(+)
diff --git a/testsuite/dwz.tests/pr24468.sh b/testsuite/dwz.tests/pr24468.sh
index 4dac9a1..7990e83 100644
--- a/testsuite/dwz.tests/pr24468.sh
+++ b/testsuite/dwz.tests/pr24468.sh
@@ -8,6 +8,7 @@ dwz -m 3 1 2
readelf -wi 1 > READELF 2>/dev/null
offsets=$(grep '(DW_TAG_partial_unit' READELF \
+ | grep -v "DW_AT_import" \
| awk '{print $1}' \
| sed 's/.*<//;s/>.*//')
for off in $offsets; do

View File

@ -0,0 +1,57 @@
[testsuite] Fix pr25109.sh on riscv64
On riscv64, I run into:
...
cc main.c no-multifile-prop-dw.S -o no-multifile-prop
no-multifile-prop-dw.S: Assembler messages:
no-multifile-prop-dw.S:25: Error: non-constant .uleb128 is not supported
make: *** [Makefile:99: no-multifile-prop] Error 1
...
Fix this by allowing to fail to build the test-case, and marking it as
unsupported.
2021-02-26 Tom de Vries <tdevries@suse.de>
* Makefile (no-multifile-prop): Add target rule.
* testsuite/dwz.tests/dwz-tests.exp: Require no-multifile-prop for
pr25109.sh.
---
Makefile | 6 +++++-
testsuite/dwz.tests/dwz-tests.exp | 3 +++
2 files changed, 8 insertions(+), 1 deletion(-)
diff --git a/Makefile b/Makefile
index d320266..7969490 100644
--- a/Makefile
+++ b/Makefile
@@ -95,9 +95,13 @@ $(TEMP_ASM_FILES): %-dw.S: $(TEST_SRC)/../lib/%.exp
export DEJAGNU=$(DEJAGNU); \
runtest --tool=dwz -srcdir $(srcdir)/testsuite/ lib/$*.exp
-$(TEST_EXECS_DWARF_ASM): %: %-dw.S
+$(filter-out no-multifile-prop, $(TEST_EXECS_DWARF_ASM)): %: %-dw.S
$(CC) $(TEST_SRC)/main.c $< -o $@
+# Fails to compile on riscv64: Error: non-constant .uleb128 is not supported.
+no-multifile-prop: %: %-dw.S
+ $(CC) $(TEST_SRC)/main.c $< -o $@ || true
+
odr-struct:
$(CXX) $(TEST_SRC)/odr.cc $(TEST_SRC)/odr-2.cc -I$(TEST_SRC) -o $@ -g \
-DKIND=struct
diff --git a/testsuite/dwz.tests/dwz-tests.exp b/testsuite/dwz.tests/dwz-tests.exp
index 48c0015..0ad77ea 100644
--- a/testsuite/dwz.tests/dwz-tests.exp
+++ b/testsuite/dwz.tests/dwz-tests.exp
@@ -86,6 +86,9 @@ foreach test $tests {
continue
}
}
+ if { $basename == "pr25109.sh" } {
+ lappend required_execs no-multifile-prop
+ }
set unsupported 0
foreach required_exec $required_execs {

View File

@ -0,0 +1,35 @@
Update SUSE Copyright years
Update the SUSE copyright range for changes made in 2020 and 2021.
2021-02-26 Tom de Vries <tdevries@suse.de>
* dwz.c: Extend SUSE Copyright range to 2021.
* COPYRIGHT_YEARS: Regenerate.
---
COPYRIGHT_YEARS | 2 +-
dwz.c | 2 +-
2 files changed, 2 insertions(+), 2 deletions(-)
diff --git a/COPYRIGHT_YEARS b/COPYRIGHT_YEARS
index fdd9942..e4b1511 100644
--- a/COPYRIGHT_YEARS
+++ b/COPYRIGHT_YEARS
@@ -1,3 +1,3 @@
-DFSF_YEARS='"1992-2021"'
-DRH_YEARS='"2001-2021"'
--DSUSE_YEARS='"2019"'
+-DSUSE_YEARS='"2019-2021"'
diff --git a/dwz.c b/dwz.c
index 3342aba..bc37f32 100644
--- a/dwz.c
+++ b/dwz.c
@@ -1,6 +1,6 @@
/* Copyright (C) 2001-2021 Red Hat, Inc.
Copyright (C) 2003 Free Software Foundation, Inc.
- Copyright (C) 2019 SUSE LLC.
+ Copyright (C) 2019-2021 SUSE LLC.
Written by Jakub Jelinek <jakub@redhat.com>, 2012.
This program is free software; you can redistribute it and/or modify

View File

@ -1,294 +0,0 @@
Update --version copyright message
[ This is a backport of master commit dda7184. Output of
contrib/gen-copyright-years.sh and dwz --version in this log message have been
updated accordingly. ]
In commit 9a663b4 "Update copyright" we've updated copyright in the sources,
but not in the --version copyright message.
Update the --version copyright message, using new script
contrib/gen-copyright-years.sh that extracts the copyright years from the
source files, and generates a file COPYRIGHT_YEARS containing define flags:
...
-DFSF_YEARS='"1992-2017"'
-DRH_YEARS='"2001-2018"'
-DSUSE_YEARS='"2019"'
...
resulting in:
...
$ dwz --version
dwz version 0.13
Copyright (C) 2001-2018 Red Hat, Inc.
Copyright (C) 1992-2017 Free Software Foundation, Inc.
Copyright (C) 2019 SUSE LLC.
...
2019-08-15 Tom de Vries <tdevries@suse.de>
* contrib/copyright-lines.awk: New file.
* contrib/gen-copyright-years.sh: New file.
* COPYRIGHT_YEARS: Generate.
* Makefile (override CFLAGS +=, dwz-for-test): Add COPYRIGHT_YEARS
defines.
* dwz.c (version): Update copyright message using COPYRIGHT_YEARS
defines.
---
COPYRIGHT_YEARS | 3 +
Makefile | 6 +-
contrib/copyright-lines.awk | 27 +++++++
contrib/gen-copyright-years.sh | 162 +++++++++++++++++++++++++++++++++++++++++
dwz.c | 5 +-
5 files changed, 199 insertions(+), 4 deletions(-)
diff --git a/COPYRIGHT_YEARS b/COPYRIGHT_YEARS
new file mode 100644
index 0000000..1dc95a5
--- /dev/null
+++ b/COPYRIGHT_YEARS
@@ -0,0 +1,3 @@
+-DFSF_YEARS='"1992-2017"'
+-DRH_YEARS='"2001-2018"'
+-DSUSE_YEARS='"2019"'
diff --git a/Makefile b/Makefile
index 7e281e5..c945c9d 100644
--- a/Makefile
+++ b/Makefile
@@ -5,7 +5,8 @@ srcdir=$(shell pwd)
endif
CFLAGS = -O2 -g
DWZ_VERSION := $(shell cat $(srcdir)/VERSION)
-override CFLAGS += -Wall -W -D_FILE_OFFSET_BITS=64 -DDWZ_VERSION='"$(DWZ_VERSION)"'
+override CFLAGS += -Wall -W -D_FILE_OFFSET_BITS=64 \
+ -DDWZ_VERSION='"$(DWZ_VERSION)"' $(shell cat $(srcdir)/COPYRIGHT_YEARS)
prefix = /usr
exec_prefix = $(prefix)
bindir = $(exec_prefix)/bin
@@ -52,7 +53,8 @@ DWZ_TEST_SOURCES := $(patsubst %.o,%-for-test.c,$(OBJECTS))
dwz-for-test: $(DWZ_TEST_SOURCES)
$(CC) $(DWZ_TEST_SOURCES) -O2 -g -lelf -o $@ -Wall -W -DDEVEL \
- -D_FILE_OFFSET_BITS=64 -DDWZ_VERSION='"for-test"' -I$(srcdir)
+ -D_FILE_OFFSET_BITS=64 -DDWZ_VERSION='"for-test"' -I$(srcdir) \
+ $(shell cat $(srcdir)/COPYRIGHT_YEARS)
min:
$(CC) $(TEST_SRC)/min.c $(TEST_SRC)/min-2.c -o $@ -g
diff --git a/contrib/copyright-lines.awk b/contrib/copyright-lines.awk
new file mode 100644
index 0000000..b031c50
--- /dev/null
+++ b/contrib/copyright-lines.awk
@@ -0,0 +1,27 @@
+BEGIN {
+ start=0
+}
+
+/Copyright \(C\).*[.]/ {
+ print
+ next
+}
+
+/Copyright \(C\)/ {
+ start=1
+ printf $0
+ next
+}
+
+/[.]/ {
+ if (start == 0)
+ next
+ print
+ start=0
+}
+
+// {
+ if (start == 0)
+ next
+ printf $0
+}
diff --git a/contrib/gen-copyright-years.sh b/contrib/gen-copyright-years.sh
new file mode 100755
index 0000000..1ef6f3f
--- /dev/null
+++ b/contrib/gen-copyright-years.sh
@@ -0,0 +1,162 @@
+#!/bin/bash
+
+this=$(basename $0)
+
+max ()
+{
+ local a
+ a=$1
+ local b
+ b=$2
+
+ if [ "$a" = "" ]; then
+ echo "$b"
+ return
+ elif [ "$b" = "" ]; then
+ echo "$a"
+ return
+ fi
+
+ if [ $a -gt $b ]; then
+ echo "$a"
+ else
+ echo "$b"
+ fi
+}
+
+min ()
+{
+ local a
+ a="$1"
+ local b
+ b="$2"
+
+ if [ "$a" = "" ]; then
+ echo "$b"
+ return
+ elif [ "$b" = "" ]; then
+ echo "$a"
+ return
+ fi
+
+ if [ $a -lt $b ]; then
+ echo "$a"
+ else
+ echo "$b"
+ fi
+}
+
+print_range () {
+ local a
+ a="$1"
+ local b
+ b="$2"
+
+ if [ "$a" = "$b" ]; then
+ echo "$a"
+ return
+ fi
+ echo "$a-$b"
+}
+
+process_line ()
+{
+ local line
+ line="$1"
+
+ fsf=false
+ rh=false
+ suse=false;
+
+ if echo "$line" \
+ | grep -q "Free Software Foundation, Inc\."; then
+ fsf=true
+ who=fsf
+ line=$(echo "$line" \
+ | sed 's/Free Software Foundation, Inc\.//')
+ elif echo "$line" \
+ | grep -q "Red Hat, Inc\."; then
+ rh=true
+ who=rh
+ line=$(echo "$line" \
+ | sed 's/Red Hat, Inc\.//')
+ elif echo "$line" \
+ | grep -q "SUSE LLC\."; then
+ suse=true
+ who=suse
+ line=$(echo "$line" \
+ | sed 's/SUSE LLC\.//')
+ else
+ echo "error: unknown copyright: $line"
+ exit 1
+ fi
+
+ line=$(echo "$line" \
+ | sed 's/[,-]/ /g')
+ max_year=$(echo "$line" \
+ | sed 's/ /\n/g' \
+ | grep -v '^$' \
+ | sort -n -r \
+ | head -n 1)
+ min_year=$(echo "$line" \
+ | sed 's/ /\n/g' \
+ | grep -v '^$' \
+ | sort -n \
+ | head -n 1)
+
+ if $fsf; then
+ fsf_max=$(max "$fsf_max" "$max_year")
+ fsf_min=$(min "$fsf_min" "$min_year")
+ elif $rh; then
+ rh_max=$(max "$rh_max" "$max_year")
+ rh_min=$(min "$rh_min" "$min_year")
+ elif $suse; then
+ suse_max=$(max "$suse_max" "$max_year")
+ suse_min=$(min "$suse_min" "$min_year")
+ fi
+}
+
+main ()
+{
+ if ! git status --ignored 2>&1 \
+ | grep -q "nothing to commit, working tree clean"; then
+ echo "Git tree not clean"
+ exit 1
+ fi
+
+ local tmp
+ tmp=$(mktemp)
+
+ for f in *.c *.h *.def; do
+ if ! grep -q "Copyright (C)" $f; then
+ echo "error: found file without copyright marker: $f"
+ exit 1
+ fi
+
+ echo processing file: $f
+
+ grep -v '"' $f \
+ | awk -f contrib/copyright-lines.awk \
+ > $tmp
+
+ while read line; do
+ line=$(echo "$line" \
+ | sed 's/ */ /g')
+ line=$(echo "$line" \
+ | sed 's/.*Copyright (C) *//')
+ echo "Processing line: $line"
+ process_line "$line"
+ done < $tmp
+ done
+
+ rm -f $tmp
+
+ echo "-DFSF_YEARS='\"$(print_range $fsf_min $fsf_max)\"'" \
+ > COPYRIGHT_YEARS
+ echo "-DRH_YEARS='\"$(print_range $rh_min $rh_max)\"'" \
+ >> COPYRIGHT_YEARS
+ echo "-DSUSE_YEARS='\"$(print_range $suse_min $suse_max)\"'" \
+ >> COPYRIGHT_YEARS
+}
+
+main "$@"
diff --git a/dwz.c b/dwz.c
index 266f56d..727314f 100644
--- a/dwz.c
+++ b/dwz.c
@@ -12395,8 +12395,9 @@ version (void)
{
fprintf (stderr,
"dwz version " DWZ_VERSION "\n"
- "Copyright (C) 2001-2012 Red Hat, Inc.\n"
- "Copyright (C) 2003 Free Software Foundation, Inc.\n"
+ "Copyright (C) " RH_YEARS " Red Hat, Inc.\n"
+ "Copyright (C) " FSF_YEARS " Free Software Foundation, Inc.\n"
+ "Copyright (C) " SUSE_YEARS " SUSE LLC.\n"
"This program is free software; you may redistribute it under the terms of\n"
"the GNU General Public License version 3 or (at your option) any later version.\n"
"This program has absolutely no warranty.\n");

13
dwz-update-version.patch Normal file
View File

@ -0,0 +1,13 @@
Update VERSION
---
VERSION | 2 +-
1 file changed, 1 insertion(+), 1 deletion(-)
diff --git a/VERSION b/VERSION
index f304084..18657cd 100644
--- a/VERSION
+++ b/VERSION
@@ -1 +1 @@
-0.13
+0.14-rc1

View File

@ -1,4 +1,45 @@
-------------------------------------------------------------------
Fri Feb 26 12:07:30 UTC 2021 - Tom de Vries <tdevries@suse.com>
- Change Version tag from 0.14rc1 to 0.14~rc1
* Rename dwz-0.14rc1.tar.xz to dwz-0.14~rc1.tar.xz
-------------------------------------------------------------------
Fri Feb 26 09:31:00 UTC 2021 - Tom de Vries <tdevries@suse.com>
- Fix testsuite build fail on riscv64:
* dwz-testsuite-fix-pr25109.sh-on-riscv64.patch
-------------------------------------------------------------------
Fri Feb 26 08:38:53 UTC 2021 - Tom de Vries <tdevries@suse.com>
- Update reported dwz version
* dwz-update-version.patch
-------------------------------------------------------------------
Fri Feb 26 07:52:22 UTC 2021 - Tom de Vries <tdevries@suse.com>
- DWZ 0.14-rc1 (master branch commit 0d391bf) update:
* Dropped patches:
- dwz-fix-assertion-off-cu_size-in-recompute_abbrevs.patch
- dwz-fix-die-no-multifile-propagation.patch
- dwz-fix-refd-NULL-assertion-in-write_die.patch
- dwz-fix-reference-from-pu-to-cu.patch
- dwz-fix-segfault-in-die_cu.patch
- dwz-testsuite-adjust-pr24468-sh-test-case-for-readelf-with-follow-links.patch
- dwz-testsuite-detect-when-devel-ignore-size-sh-is-unsupported.patch
- dwz-testsuite-fix-partial-unit-grepping-in-pr24468-sh.patch
- dwz-update-version-copyright-message.patch
* Added patches:
- dwz-add-assert-checking-that-cu-is-not-referenced-from-pu.patch
- dwz-call-reorder_dups-asap.patch
- dwz-document-experimental-status-of-odr.patch
- dwz-enable-odr-by-default.patch
- dwz-fix-reference-of-pu-to-cu-for-odr.patch
- dwz-precompute-partitions.patch
- dwz-update-suse-copyright-years.patch
* Added BuildRequires gcc-c++
-------------------------------------------------------------------
Thu Jan 7 10:21:31 UTC 2021 - Tom de Vries <tdevries@suse.com>
- Fix pr24468.sh test-case with newer readelf.

View File

@ -1,5 +1,5 @@
#
# spec file for package dwz
# spec file for package dwz%{name_suffix}
#
# Copyright (c) 2021 SUSE LLC
#
@ -32,7 +32,7 @@ ExclusiveArch: do_not_build
%endif
%if %{build_testsuite}
%define debug_package %{nil}
%define debug_package %{nil}
%endif
%if %{build_main}
@ -42,7 +42,7 @@ ExclusiveArch: do_not_build
%endif
Name: dwz%{name_suffix}
Version: 0.13
Version: 0.14~rc1
Release: 0
%if %{build_main}
Summary: DWARF optimization and duplicate removal tool
@ -63,6 +63,7 @@ BuildRequires: xz
%if %{build_testsuite}
BuildRequires: dejagnu
BuildRequires: elfutils
BuildRequires: gcc-c++
BuildRequires: gdb
%ifnarch riscv64
BuildRequires: binutils-gold
@ -79,15 +80,15 @@ NoSource: 0
Source1: dwz-rpmlintrc
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
Patch6: dwz-fix-segfault-in-die_cu.patch
Patch7: dwz-testsuite-detect-when-devel-ignore-size-sh-is-unsupported.patch
Patch8: dwz-testsuite-adjust-pr24468-sh-test-case-for-readelf-with-follow-links.patch
Patch9: dwz-testsuite-fix-partial-unit-grepping-in-pr24468-sh.patch
Patch1: dwz-precompute-partitions.patch
Patch2: dwz-call-reorder_dups-asap.patch
Patch3: dwz-fix-reference-of-pu-to-cu-for-odr.patch
Patch4: dwz-add-assert-checking-that-cu-is-not-referenced-from-pu.patch
Patch5: dwz-enable-odr-by-default.patch
Patch6: dwz-document-experimental-status-of-odr.patch
Patch7: dwz-update-suse-copyright-years.patch
Patch8: dwz-update-version.patch
Patch9: dwz-testsuite-fix-pr25109.sh-on-riscv64.patch
%if %{build_main}
%description