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 9816D3857800 for ; Mon, 14 Sep 2020 10:24:30 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 9816D3857800 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=klomp.org Authentication-Results: sourceware.org; spf=none smtp.mailfrom=mark@tarox.wildebeest.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 70239300D923; Mon, 14 Sep 2020 12:24:29 +0200 (CEST) Received: by tarox.wildebeest.org (Postfix, from userid 1000) id 66A944000CBE; Mon, 14 Sep 2020 12:24:29 +0200 (CEST) From: Mark Wielaard To: dwz@sourceware.org Cc: Mark Wielaard Subject: [PATCH 4/4] Handle new DWARF5 operations as their GNU extension variants. Date: Mon, 14 Sep 2020 12:23:55 +0200 Message-Id: <20200914102355.8137-5-mark@klomp.org> X-Mailer: git-send-email 2.18.4 In-Reply-To: <20200914102355.8137-1-mark@klomp.org> References: <20200914102355.8137-1-mark@klomp.org> X-Spam-Status: No, score=-35.9 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, KHOP_HELO_FCRDNS, SPF_HELO_NONE, SPF_NONE, 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: Mon, 14 Sep 2020 10:24:32 -0000 This handles DW_OP_implicit_pointer, DW_OP_entry_value, DW_OP_const_type, DW_OP_regval_type, DW_OP_deref_type, DW_OP_convert, DW_OP_reinterpret as the DW_OP_GNU extensions for pre-DWARF5. This doesn't handle the new DW_OP_addrx and DW_OP_constx which are used with split-dwarf .debug_addr tables. Nor does it implement DW_OP_xderef_type which gcc will never emit. * dwz.c (read_exprloc): Handle DW_OP_implicit_pointer, DW_OP_entry_value, DW_OP_convert, DW_OP_reinterpret, DW_OP_regval_type, DW_OP_const_type and DW_OP_deref_type. (read_exprloc_low_mem_phase1): Likewise. (adjust_exprloc): Likewise. --- dwz.c | 39 ++++++++++++++++++++++++++++++--------- 1 file changed, 30 insertions(+), 9 deletions(-) diff --git a/dwz.c b/dwz.c index b497c5f..02e984e 100644 --- a/dwz.c +++ b/dwz.c @@ -1996,6 +1996,7 @@ read_exprloc (DSO *dso, dw_die_ref die, unsigned char *ptr, size_t len, break; case DW_OP_call_ref: case DW_OP_GNU_implicit_pointer: + case DW_OP_implicit_pointer: case DW_OP_GNU_variable_value: cu = die_cu (die); addr = read_size (ptr, cu->cu_version == 2 ? ptr_size : 4); @@ -2023,7 +2024,7 @@ read_exprloc (DSO *dso, dw_die_ref die, unsigned char *ptr, size_t len, die->die_ck_state = CK_BAD; if (need_adjust) *need_adjust = true; - if (op == DW_OP_GNU_implicit_pointer) + if (op == DW_OP_GNU_implicit_pointer || op == DW_OP_implicit_pointer) skip_leb128 (ptr); break; case DW_OP_const8u: @@ -2051,12 +2052,13 @@ read_exprloc (DSO *dso, dw_die_ref die, unsigned char *ptr, size_t len, } break; case DW_OP_GNU_entry_value: + case DW_OP_entry_value: { uint32_t leni = read_uleb128 (ptr); if ((uint64_t) (end - ptr) < leni) { - error (0, 0, "%s: DWARF DW_OP_GNU_entry_value with too large" - " length", dso->filename); + error (0, 0, "%s: %s with too large length", + get_DW_OP_str (op), dso->filename); return 1; } if (read_exprloc (dso, die, ptr, leni, need_adjust)) @@ -2065,20 +2067,25 @@ read_exprloc (DSO *dso, dw_die_ref die, unsigned char *ptr, size_t len, } break; case DW_OP_GNU_convert: + case DW_OP_convert: case DW_OP_GNU_reinterpret: + case DW_OP_reinterpret: addr = read_uleb128 (ptr); if (addr == 0) break; goto typed_dwarf; case DW_OP_GNU_regval_type: + case DW_OP_regval_type: skip_leb128 (ptr); addr = read_uleb128 (ptr); goto typed_dwarf; case DW_OP_GNU_const_type: + case DW_OP_const_type: addr = read_uleb128 (ptr); ptr += *ptr + 1; goto typed_dwarf; case DW_OP_GNU_deref_type: + case DW_OP_deref_type: ++ptr; addr = read_uleb128 (ptr); typed_dwarf: @@ -2231,6 +2238,7 @@ read_exprloc_low_mem_phase1 (DSO *dso, dw_die_ref die, unsigned char *ptr, break; case DW_OP_call_ref: case DW_OP_GNU_implicit_pointer: + case DW_OP_implicit_pointer: case DW_OP_GNU_variable_value: cu = die_cu (die); addr = read_size (ptr, cu->cu_version == 2 ? ptr_size : 4); @@ -2242,7 +2250,7 @@ read_exprloc_low_mem_phase1 (DSO *dso, dw_die_ref die, unsigned char *ptr, necessary if die_cu (ref) != cu, but we don't track cu's during low-mem phase1. */ add_dummy_die (cu, addr); - if (op == DW_OP_GNU_implicit_pointer) + if (op == DW_OP_GNU_implicit_pointer || op == DW_OP_implicit_pointer) skip_leb128 (ptr); break; case DW_OP_const8u: @@ -2270,12 +2278,13 @@ read_exprloc_low_mem_phase1 (DSO *dso, dw_die_ref die, unsigned char *ptr, } break; case DW_OP_GNU_entry_value: + case DW_OP_entry_value: { uint32_t leni = read_uleb128 (ptr); if ((uint64_t) (end - ptr) < leni) { - error (0, 0, "%s: DWARF DW_OP_GNU_entry_value with too large" - " length", dso->filename); + error (0, 0, "%s: %s with too large length", + get_DW_OP_str (op), dso->filename); return 1; } if (read_exprloc_low_mem_phase1 (dso, die, ptr, leni)) @@ -2284,18 +2293,23 @@ read_exprloc_low_mem_phase1 (DSO *dso, dw_die_ref die, unsigned char *ptr, } break; case DW_OP_GNU_convert: + case DW_OP_convert: case DW_OP_GNU_reinterpret: + case DW_OP_reinterpret: skip_leb128 (ptr); break; case DW_OP_GNU_regval_type: + case DW_OP_regval_type: skip_leb128 (ptr); skip_leb128 (ptr); break; case DW_OP_GNU_const_type: - skip_leb128 (ptr); + case DW_OP_const_type: + read_uleb128 (ptr); ptr += *ptr + 1; break; case DW_OP_GNU_deref_type: + case DW_OP_deref_type: ++ptr; skip_leb128 (ptr); break; @@ -11042,6 +11056,7 @@ adjust_exprloc (dw_cu_ref cu, dw_die_ref die, dw_cu_ref refcu, break; case DW_OP_call_ref: case DW_OP_GNU_implicit_pointer: + case DW_OP_implicit_pointer: case DW_OP_GNU_variable_value: addr = read_size (ptr, refcu->cu_version == 2 ? ptr_size : 4); assert (cu->cu_version == refcu->cu_version); @@ -11059,7 +11074,7 @@ adjust_exprloc (dw_cu_ref cu, dw_die_ref die, dw_cu_ref refcu, ptr += ptr_size; else ptr += 4; - if (op == DW_OP_GNU_implicit_pointer) + if (op == DW_OP_GNU_implicit_pointer || op == DW_OP_implicit_pointer) skip_leb128 (ptr); break; case DW_OP_const8u: @@ -11085,28 +11100,34 @@ adjust_exprloc (dw_cu_ref cu, dw_die_ref die, dw_cu_ref refcu, ptr += leni; break; case DW_OP_GNU_entry_value: + case DW_OP_entry_value: leni = read_uleb128 (ptr); assert ((uint64_t) (end - ptr) >= leni); adjust_exprloc (cu, die, refcu, ref, ptr, leni); ptr += leni; break; case DW_OP_GNU_convert: + case DW_OP_convert: case DW_OP_GNU_reinterpret: + case DW_OP_reinterpret: orig_ptr = ptr; addr = read_uleb128 (ptr); if (addr == 0) break; goto typed_dwarf; case DW_OP_GNU_regval_type: + case DW_OP_regval_type: skip_leb128 (ptr); orig_ptr = ptr; addr = read_uleb128 (ptr); goto typed_dwarf; case DW_OP_GNU_const_type: + case DW_OP_const_type: orig_ptr = ptr; addr = read_uleb128 (ptr); goto typed_dwarf; case DW_OP_GNU_deref_type: + case DW_OP_deref_type: ++ptr; orig_ptr = ptr; addr = read_uleb128 (ptr); @@ -11129,7 +11150,7 @@ adjust_exprloc (dw_cu_ref cu, dw_die_ref die, dw_cu_ref refcu, *ptr++ = 0x80; *ptr++ = 0; } - if (op == DW_OP_GNU_const_type) + if (op == DW_OP_GNU_const_type || op == DW_OP_const_type) ptr += *ptr + 1; break; default: -- 2.18.4