From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 84640 invoked by alias); 8 Nov 2019 17:11:09 -0000 Mailing-List: contact dwz-help@sourceware.org; run by ezmlm Precedence: bulk List-Id: List-Post: List-Help: List-Subscribe: Sender: dwz-owner@sourceware.org Received: (qmail 84628 invoked by uid 89); 8 Nov 2019 17:11:09 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Checked: by ClamAV 0.100.3 on sourceware.org X-Virus-Found: No X-Spam-SWARE-Status: No, score=-25.2 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,SPF_PASS autolearn=ham version=3.3.1 spammy=HX-Languages-Length:2608 X-Spam-Status: No, score=-25.2 required=5.0 tests=AWL,BAYES_00,GIT_PATCH_0,GIT_PATCH_1,GIT_PATCH_2,GIT_PATCH_3,SPF_PASS autolearn=ham version=3.3.1 X-Spam-Checker-Version: SpamAssassin 3.3.1 (2010-03-16) on sourceware.org X-Spam-Level: X-HELO: mx1.suse.de X-Virus-Scanned: by amavisd-new at test-mx.suse.de Date: Tue, 01 Jan 2019 00:00:00 -0000 From: Tom de Vries To: dwz@sourceware.org, jakub@redhat.com Subject: [committed] Clear struct dw_die's u.p2 field before use in 'phase 2' Message-ID: <20191108171102.GA20300@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-SW-Source: 2019-q4/txt/msg00041.txt.bz2 Hi, In struct dw_die we have a union u with fields p1 and p2. The p1 field is used during 'phase 1', after which the space is reused for the p2 field during 'phase 2'. While developing a patch for dwz, I ran into a case where a 'die->u.p2.die_new_offset != 0' assert in write_die did not trigger, because die->u.p1 was used during 'phase 1' which left a non-zero value in die->u.p2.die_new_offset. Add initialization that clears the 'phase 2' field u.p2 before 'phase 2', to increase the chance of triggering this type of assert. Enable this only with -DDEVEL, since it increases runtime with ~1%. Committed to trunk. Thanks, - Tom Clear struct dw_die's u.p2 field before use in 'phase 2' 2019-11-08 Tom de Vries * dwz.c (clear_p2_field): New function. (write_multifile, dw, optimize_multifile): Call clear_p2_field. --- dwz.c | 34 ++++++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/dwz.c b/dwz.c index 6e1c997..ec9a79a 100644 --- a/dwz.c +++ b/dwz.c @@ -11474,6 +11474,29 @@ write_multifile_line (void) return ret; } +#if DEVEL +/* In struct dw_die we have a union u with fields p1 and p2. The p1 field is + used during phase 1, after which the space is reused for the p2 field + during phase 2. Clear the p2 field to get rid of values stored to p1 + during phase 1. */ +static int +clear_p2_field (void) +{ + dw_cu_ref cu; + dw_die_ref die; + + FOREACH_DIE (cu, die) + { + assert (die->die_collapsed_child == 0); + die->u.p2.die_new_abbrev = NULL; + die->u.p2.die_new_offset = 0; + die->u.p2.die_intracu_udata_size = 0; + } + + return 0; +} +#endif + /* Collect potentially shareable DIEs, strings and .debug_macro opcode sequences into temporary .debug_* files. */ static int @@ -11500,6 +11523,10 @@ write_multifile (DSO *dso) multi_ptr_size = ptr_size; multi_endian = do_read_32 == buf_read_ule32 ? ELFDATA2LSB : ELFDATA2MSB; +#if DEVEL + clear_p2_field (); +#endif + for (i = 0; i < SAVED_SECTIONS; i++) { saved_new_data[i] = debug_sections[i].new_data; @@ -11812,6 +11839,9 @@ dwz (const char *file, const char *outfile, struct file_result *res, && (remove_empty_pus () || read_macro (dso))) || read_debug_info (dso, DEBUG_TYPES) +#if DEVEL + || clear_p2_field () +#endif || compute_abbrevs (dso) || (unlikely (fi_multifile) && (finalize_strp (false), 0))) { @@ -12127,6 +12157,10 @@ optimize_multifile (void) || partition_dups ()) goto fail; +#if DEVEL + clear_p2_field (); +#endif + for (cup = &first_cu; *cup && (*cup)->cu_kind == CU_PU; cup = &(*cup)->cu_next) ;