diff --git a/dwz-0.13.tar.xz b/dwz-0.13.tar.xz deleted file mode 100644 index 02bf0e9..0000000 --- a/dwz-0.13.tar.xz +++ /dev/null @@ -1,3 +0,0 @@ -version https://git-lfs.github.com/spec/v1 -oid sha256:8da2495d666ba94c1d9b0eca0799e32fc4553d5cbcc8eadfe90d7ca48cf4f5b0 -size 113616 diff --git a/dwz-0.14~rc1.tar.xz b/dwz-0.14~rc1.tar.xz new file mode 100644 index 0000000..7aabe98 --- /dev/null +++ b/dwz-0.14~rc1.tar.xz @@ -0,0 +1,3 @@ +version https://git-lfs.github.com/spec/v1 +oid sha256:370e7c0c09fc68e12fcff237a76b9eb3553833cbeeec6ae12e6c12f41eb9e289 +size 146372 diff --git a/dwz-add-assert-checking-that-cu-is-not-referenced-from-pu.patch b/dwz-add-assert-checking-that-cu-is-not-referenced-from-pu.patch new file mode 100644 index 0000000..1727435 --- /dev/null +++ b/dwz-add-assert-checking-that-cu-is-not-referenced-from-pu.patch @@ -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 + + * 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) + { diff --git a/dwz-call-reorder_dups-asap.patch b/dwz-call-reorder_dups-asap.patch new file mode 100644 index 0000000..0c3e91c --- /dev/null +++ b/dwz-call-reorder_dups-asap.patch @@ -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 + + 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)) + { diff --git a/dwz-document-experimental-status-of-odr.patch b/dwz-document-experimental-status-of-odr.patch new file mode 100644 index 0000000..b5e88c3 --- /dev/null +++ b/dwz-document-experimental-status-of-odr.patch @@ -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 + + 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= diff --git a/dwz-enable-odr-by-default.patch b/dwz-enable-odr-by-default.patch new file mode 100644 index 0000000..7dcb14a --- /dev/null +++ b/dwz-enable-odr-by-default.patch @@ -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= + 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", "", "link", + "Set aggressiveness level of one definition rule optimization." }, diff --git a/dwz-fix-assertion-off-cu_size-in-recompute_abbrevs.patch b/dwz-fix-assertion-off-cu_size-in-recompute_abbrevs.patch deleted file mode 100644 index ac42161..0000000 --- a/dwz-fix-assertion-off-cu_size-in-recompute_abbrevs.patch +++ /dev/null @@ -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>: Abbrev Number: 65 (DW_TAG_formal_parameter) - DW_AT_type : <0xe33be> - 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 - - 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 diff --git a/dwz-fix-die-no-multifile-propagation.patch b/dwz-fix-die-no-multifile-propagation.patch deleted file mode 100644 index f396650..0000000 --- a/dwz-fix-die-no-multifile-propagation.patch +++ /dev/null @@ -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 - - * 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 - - 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; diff --git a/dwz-fix-refd-NULL-assertion-in-write_die.patch b/dwz-fix-refd-NULL-assertion-in-write_die.patch deleted file mode 100644 index e59fe64..0000000 --- a/dwz-fix-refd-NULL-assertion-in-write_die.patch +++ /dev/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 - - 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 - #include - #include -+#include - #include - #include - #include -@@ -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) diff --git a/dwz-fix-reference-from-pu-to-cu.patch b/dwz-fix-reference-from-pu-to-cu.patch deleted file mode 100644 index 77f22b3..0000000 --- a/dwz-fix-reference-from-pu-to-cu.patch +++ /dev/null @@ -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 - - 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); diff --git a/dwz-fix-reference-of-pu-to-cu-for-odr.patch b/dwz-fix-reference-of-pu-to-cu-for-odr.patch new file mode 100644 index 0000000..d3248fe --- /dev/null +++ b/dwz-fix-reference-of-pu-to-cu-for-odr.patch @@ -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 + + 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); + } + diff --git a/dwz-fix-segfault-in-die_cu.patch b/dwz-fix-segfault-in-die_cu.patch deleted file mode 100644 index 9e849a3..0000000 --- a/dwz-fix-segfault-in-die_cu.patch +++ /dev/null @@ -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 - - 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)); diff --git a/dwz-precompute-partitions.patch b/dwz-precompute-partitions.patch new file mode 100644 index 0000000..70d77f2 --- /dev/null +++ b/dwz-precompute-partitions.patch @@ -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 + + * 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; diff --git a/dwz-testsuite-adjust-pr24468-sh-test-case-for-readelf-with-follow-links.patch b/dwz-testsuite-adjust-pr24468-sh-test-case-for-readelf-with-follow-links.patch deleted file mode 100644 index 54ebfde..0000000 --- a/dwz-testsuite-adjust-pr24468-sh-test-case-for-readelf-with-follow-links.patch +++ /dev/null @@ -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}' \ diff --git a/dwz-testsuite-detect-when-devel-ignore-size-sh-is-unsupported.patch b/dwz-testsuite-detect-when-devel-ignore-size-sh-is-unsupported.patch deleted file mode 100644 index 660527d..0000000 --- a/dwz-testsuite-detect-when-devel-ignore-size-sh-is-unsupported.patch +++ /dev/null @@ -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 - - 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 - diff --git a/dwz-testsuite-fix-partial-unit-grepping-in-pr24468-sh.patch b/dwz-testsuite-fix-partial-unit-grepping-in-pr24468-sh.patch deleted file mode 100644 index 6f1407f..0000000 --- a/dwz-testsuite-fix-partial-unit-grepping-in-pr24468-sh.patch +++ /dev/null @@ -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 - - * 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/.*.*//') - for off in $offsets; do diff --git a/dwz-testsuite-fix-pr25109.sh-on-riscv64.patch b/dwz-testsuite-fix-pr25109.sh-on-riscv64.patch new file mode 100644 index 0000000..fd4c6e7 --- /dev/null +++ b/dwz-testsuite-fix-pr25109.sh-on-riscv64.patch @@ -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 + + * 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 { diff --git a/dwz-update-suse-copyright-years.patch b/dwz-update-suse-copyright-years.patch new file mode 100644 index 0000000..9db1283 --- /dev/null +++ b/dwz-update-suse-copyright-years.patch @@ -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 + + * 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 , 2012. + + This program is free software; you can redistribute it and/or modify diff --git a/dwz-update-version-copyright-message.patch b/dwz-update-version-copyright-message.patch deleted file mode 100644 index 0353a39..0000000 --- a/dwz-update-version-copyright-message.patch +++ /dev/null @@ -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 - - * 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"); diff --git a/dwz-update-version.patch b/dwz-update-version.patch new file mode 100644 index 0000000..fc94a34 --- /dev/null +++ b/dwz-update-version.patch @@ -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 diff --git a/dwz.changes b/dwz.changes index 459b3d3..720d13c 100644 --- a/dwz.changes +++ b/dwz.changes @@ -1,4 +1,45 @@ ------------------------------------------------------------------- +Fri Feb 26 12:07:30 UTC 2021 - Tom de Vries + +- 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 + +- 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 + +- Update reported dwz version + * dwz-update-version.patch + +------------------------------------------------------------------- +Fri Feb 26 07:52:22 UTC 2021 - Tom de Vries + +- 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 - Fix pr24468.sh test-case with newer readelf. diff --git a/dwz.spec b/dwz.spec index 90c50c1..37e4707 100644 --- a/dwz.spec +++ b/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