From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from mx2.suse.de (mx2.suse.de [195.135.220.15]) by sourceware.org (Postfix) with ESMTPS id 9B71B3854804 for ; Tue, 16 Mar 2021 15:55:00 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 9B71B3854804 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=suse.de Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=tdevries@suse.de X-Virus-Scanned: by amavisd-new at test-mx.suse.de Received: from relay2.suse.de (unknown [195.135.221.27]) by mx2.suse.de (Postfix) with ESMTP id AA55CAD72; Tue, 16 Mar 2021 15:54:59 +0000 (UTC) Date: Tue, 16 Mar 2021 16:54:57 +0100 From: Tom de Vries To: dwz@sourceware.org, jakub@redhat.com, mark@klomp.org Subject: [committed] Handle reordered dup chains in create_import_tree Message-ID: <20210316155456.GA32267@delia> MIME-Version: 1.0 Content-Type: text/plain; charset=us-ascii Content-Disposition: inline User-Agent: Mutt/1.10.1 (2018-07-13) X-Spam-Status: No, score=-12.2 required=5.0 tests=BAYES_00, GIT_PATCH_0, KAM_DMARC_STATUS, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: dwz@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Dwz mailing list List-Unsubscribe: , List-Archive: List-Help: List-Subscribe: , X-List-Received-Date: Tue, 16 Mar 2021 15:55:02 -0000 Hi, With the test-case from PR27578, we run into: ... $ dwz libvclplug_genlo.so.debug -o libvclplug_genlo.so.debug.z \ -lnone --odr --devel-progress create_import_tree phase 2 dwz: dwz.c:8833: remove_import_edges: Assertion `i == cucount' failed. Aborted (core dumped) ... Using --devel-verify-edges, we can trigger an assert earlier: ... create_import_tree phase 1 dwz: dwz.c:8923: verify_edges_1: \ Assertion `count == 0 || e1->icu->idx > last_idx' failed. Aborted (core dumped) ... where e1->icu->idx == 201 and last_idx == 201. The problem is (as we can see using --devel-dump-edges) that there's a duplicate edge from CU 201 to PU 48: ... idx: 48 cu: 0xbc incoming: 200 incoming: 201 incoming: 201 incoming: 203 incoming: 204 incoming: 208 ... This can be traced back to this duplicate chain: ... duplicate chain: 7fe2 O 2de8b1f3(fc1aa040) 2de8b1f3 Visual structure_type DECL 19d67 O 2de8b1f3(fc1aa040) 2de8b1f3 Visual structure_type DECL 2a7aa O 2de8b1f3(fc1aa040) 2de8b1f3 Visual structure_type DECL 41434 O 2de8b1f3(fc1aa040) 2de8b1f3 Visual structure_type DECL Compilation Unit @ offset 0x5bf84: 5fd9d O 2de8b1f3(fc1aa040) 2de8b1f3 Visual structure_type DECL 611f5 O 2de8b1f3(deb4b00f) 2de8b1f3 Visual structure_type DEF ... Since it starts with a DECL, it will be reordered such that the DEF is at the start. However, that breaks the code in create_import_tree that checks for duplicate chain members from the same CU, which assumes that those are adjacent. Fix this in create_import_tree. Committed to trunk. Thanks, - Tom Handle reordered dup chains in create_import_tree 2021-03-16 Tom de Vries PR dwz/27578 * dwz.c (create_import_tree): Handle reorder duplicate chain. --- dwz.c | 18 ++++++++++++++++-- 1 file changed, 16 insertions(+), 2 deletions(-) diff --git a/dwz.c b/dwz.c index 11c9114..d72ec28 100644 --- a/dwz.c +++ b/dwz.c @@ -9135,11 +9135,18 @@ create_import_tree (void) ipu->cu = pu; pu->u1.cu_icu = ipu; assert (rdie->die_toplevel); + dw_die_ref firstdie = NULL; + dw_cu_ref firstdiecu = NULL; for (die = rdie->die_nextdup, prev_cu = NULL; die; die = die->die_nextdup) { dw_cu_ref diecu = die_cu (die); - if (diecu == prev_cu) + if (firstdie == NULL) + { + firstdie = die; + firstdiecu = die_cu (firstdie); + } + if (diecu == prev_cu || (die != firstdie && diecu == firstdiecu)) continue; ipu->incoming_count++; size += 1 + (diecu->cu_version == 2 ? ptr_size : 4); @@ -9149,11 +9156,18 @@ create_import_tree (void) obstack_alloc (&ob2, ipu->incoming_count * sizeof (*ipu->incoming)); + firstdie = NULL; + firstdiecu = NULL; for (die = rdie->die_nextdup, i = 0, prev_cu = NULL; die; die = die->die_nextdup) { dw_cu_ref diecu = die_cu (die); - if (diecu == prev_cu) + if (firstdie == NULL) + { + firstdie = die; + firstdiecu = die_cu (firstdie); + } + if (diecu == prev_cu || (die != firstdie && diecu == firstdiecu)) continue; icu = diecu->u1.cu_icu; if (icu == NULL)