Accepting request 875368 from home:tomdevries:branches:devel:tools:compiler-dwz-pre-release-0.14
- Change Version tag from 0.14rc1 to 0.14~rc1 * Rename dwz-0.14rc1.tar.xz to dwz-0.14~rc1.tar.xz - Fix testsuite build fail on riscv64: * dwz-testsuite-fix-pr25109.sh-on-riscv64.patch - Update reported dwz version * dwz-update-version.patch - 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++ OBS-URL: https://build.opensuse.org/request/show/875368 OBS-URL: https://build.opensuse.org/package/show/devel:tools:compiler/dwz?expand=0&rev=34
This commit is contained in:
parent
fe44ecf795
commit
ef157f6ece
@ -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
3
dwz-0.14~rc1.tar.xz
Normal file
@ -0,0 +1,3 @@
|
||||
version https://git-lfs.github.com/spec/v1
|
||||
oid sha256:370e7c0c09fc68e12fcff237a76b9eb3553833cbeeec6ae12e6c12f41eb9e289
|
||||
size 146372
|
@ -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)
|
||||
{
|
64
dwz-call-reorder_dups-asap.patch
Normal file
64
dwz-call-reorder_dups-asap.patch
Normal 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))
|
||||
{
|
32
dwz-document-experimental-status-of-odr.patch
Normal file
32
dwz-document-experimental-status-of-odr.patch
Normal 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>
|
44
dwz-enable-odr-by-default.patch
Normal file
44
dwz-enable-odr-by-default.patch
Normal 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." },
|
@ -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
|
@ -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;
|
@ -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)
|
@ -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);
|
69
dwz-fix-reference-of-pu-to-cu-for-odr.patch
Normal file
69
dwz-fix-reference-of-pu-to-cu-for-odr.patch
Normal 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);
|
||||
}
|
||||
|
@ -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));
|
165
dwz-precompute-partitions.patch
Normal file
165
dwz-precompute-partitions.patch
Normal 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;
|
@ -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}' \
|
@ -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
|
||||
|
@ -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
|
57
dwz-testsuite-fix-pr25109.sh-on-riscv64.patch
Normal file
57
dwz-testsuite-fix-pr25109.sh-on-riscv64.patch
Normal 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 {
|
35
dwz-update-suse-copyright-years.patch
Normal file
35
dwz-update-suse-copyright-years.patch
Normal 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
|
@ -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
13
dwz-update-version.patch
Normal 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
|
41
dwz.changes
41
dwz.changes
@ -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.
|
||||
|
25
dwz.spec
25
dwz.spec
@ -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
|
||||
|
Loading…
Reference in New Issue
Block a user