From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from gnu.wildebeest.org (wildebeest.demon.nl [212.238.236.112]) by sourceware.org (Postfix) with ESMTPS id 047CC3854802 for ; Sun, 17 Jan 2021 22:29:17 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 047CC3854802 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=klomp.org Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=mark@klomp.org Received: from tarox.wildebeest.org (tarox.wildebeest.org [172.31.17.39]) (using TLSv1.2 with cipher AECDH-AES256-SHA (256/256 bits)) (No client certificate requested) by gnu.wildebeest.org (Postfix) with ESMTPSA id BB26530015C3; Sun, 17 Jan 2021 23:29:15 +0100 (CET) Received: by tarox.wildebeest.org (Postfix, from userid 1000) id A8ED140007B5; Sun, 17 Jan 2021 23:29:15 +0100 (CET) From: Mark Wielaard To: dwz@sourceware.org Cc: Mark Wielaard Subject: [PATCH] Break out of while loop correctly to make sure loclists are adjusted. Date: Sun, 17 Jan 2021 23:25:59 +0100 Message-Id: <20210117222559.23364-1-mark@klomp.org> X-Mailer: git-send-email 2.18.4 X-Spam-Status: No, score=-11.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_DMARC_STATUS, 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: Sun, 17 Jan 2021 22:29:18 -0000 The reading and adjusting of DWARF5 .debug_loclists was modelled on the DWARF4 .debug_loc section parsing. The .debug_loc parsing used a while loop and breaks out when done. But .debug_loclists use a switch statement inside the while loop, so break doesn't actually break out of the loop when done, and return on end of list exits the functions too early. This meant that although the loclists were parsed correctly, then were then not actually adjusted. Fix this by using gotos inside the switch statements. * dwz.c (read_loclist_low_mem_phase1): Use again and done labels to goto inside switch. (read_loclist): Likewise. (adjust_loclist): Likewise. --- dwz.c | 30 ++++++++++++++++++------------ 1 file changed, 18 insertions(+), 12 deletions(-) diff --git a/dwz.c b/dwz.c index b3cf346..8903570 100644 --- a/dwz.c +++ b/dwz.c @@ -2807,6 +2807,7 @@ read_loclist_low_mem_phase1 (DSO *dso, dw_cu_ref cu, dw_die_ref die, } endsec = ptr + debug_sections[sec].size; ptr += offset; +again: while (ptr < endsec) { if (sec == DEBUG_LOC) @@ -2828,11 +2829,11 @@ read_loclist_low_mem_phase1 (DSO *dso, dw_cu_ref cu, dw_die_ref die, switch (lle) { case DW_LLE_end_of_list: - return 0; + goto done; case DW_LLE_base_addressx: skip_leb128 (ptr); - continue; + goto again; case DW_LLE_startx_endx: skip_leb128 (ptr); @@ -2858,7 +2859,7 @@ read_loclist_low_mem_phase1 (DSO *dso, dw_cu_ref cu, dw_die_ref die, case DW_LLE_base_address: ptr += ptr_size; - continue; + goto again; case DW_LLE_start_end: ptr += 2 * ptr_size; @@ -2878,7 +2879,7 @@ read_loclist_low_mem_phase1 (DSO *dso, dw_cu_ref cu, dw_die_ref die, dso->filename, cu->cu_version); skip_leb128 (ptr); skip_leb128 (ptr); - continue; + goto again; default: error (0, 0, @@ -2903,6 +2904,7 @@ read_loclist_low_mem_phase1 (DSO *dso, dw_cu_ref cu, dw_die_ref die, ptr += len; } +done: return 0; } @@ -3061,6 +3063,7 @@ read_loclist (DSO *dso, dw_cu_ref cu, dw_die_ref die, GElf_Addr offset) } endsec = ptr + debug_sections[sec].size; ptr += offset; +again: while (ptr < endsec) { if (cu->cu_version < 5) @@ -3082,11 +3085,11 @@ read_loclist (DSO *dso, dw_cu_ref cu, dw_die_ref die, GElf_Addr offset) switch (lle) { case DW_LLE_end_of_list: - return 0; + goto done; case DW_LLE_base_addressx: skip_leb128 (ptr); - continue; + goto again; case DW_LLE_startx_endx: skip_leb128 (ptr); @@ -3112,7 +3115,7 @@ read_loclist (DSO *dso, dw_cu_ref cu, dw_die_ref die, GElf_Addr offset) case DW_LLE_base_address: ptr += ptr_size; - continue; + goto again; case DW_LLE_start_end: ptr += 2 * ptr_size; @@ -3132,7 +3135,7 @@ read_loclist (DSO *dso, dw_cu_ref cu, dw_die_ref die, GElf_Addr offset) dso->filename, cu->cu_version); skip_leb128 (ptr); skip_leb128 (ptr); - continue; + goto again; default: error (0, 0, @@ -3156,6 +3159,7 @@ read_loclist (DSO *dso, dw_cu_ref cu, dw_die_ref die, GElf_Addr offset) ptr += len; } +done: if (need_adjust) { struct debug_loc_adjust adj, *a; @@ -12708,17 +12712,18 @@ adjust_loclists (void **slot, void *data) ptr = debug_sections[DEBUG_LOCLISTS].new_data + adj->start_offset; endsec = ptr + debug_sections[DEBUG_LOCLISTS].size; +again: while (ptr < endsec) { uint8_t lle = *ptr++; switch (lle) { case DW_LLE_end_of_list: - return 1; + goto done; case DW_LLE_base_addressx: skip_leb128 (ptr); - continue; + goto again; case DW_LLE_startx_endx: skip_leb128 (ptr); @@ -12744,7 +12749,7 @@ adjust_loclists (void **slot, void *data) case DW_LLE_base_address: ptr += ptr_size; - continue; + goto again; case DW_LLE_start_end: ptr += 2 * ptr_size; @@ -12762,7 +12767,7 @@ adjust_loclists (void **slot, void *data) warning on the original parsing if CU version is not 5.*/ skip_leb128 (ptr); skip_leb128 (ptr); - continue; + goto again; default: error (0, 0, "unhandled location list entry 0x%x", lle); @@ -12777,6 +12782,7 @@ adjust_loclists (void **slot, void *data) ptr += len; } +done: return 1; } -- 2.18.4