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 82E3B398797F for ; Mon, 14 Sep 2020 10:24:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 82E3B398797F 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 6265B300BC89; Mon, 14 Sep 2020 12:24:22 +0200 (CEST) Received: by tarox.wildebeest.org (Postfix, from userid 1000) id 5CB534000CBE; Mon, 14 Sep 2020 12:24:22 +0200 (CEST) From: Mark Wielaard To: dwz@sourceware.org Cc: Mark Wielaard Subject: [PATCH 2/4] Handle DWARF5 headers for compile and partial units. Date: Mon, 14 Sep 2020 12:23:53 +0200 Message-Id: <20200914102355.8137-3-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=-36.6 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:25 -0000 DWARF5 also has separate unit headers for types (replacing .debug_types) and unit types for split-DWARF both a skeleton tree as compile and split trees. Which aren't handled yet. * dwz.c (get_DW_UT_str): New function. (read_debug_line): Add .debug_line in version message error string. (try_debug_info): Parse cu_version 5 header for DW_UT_compile and DW_UT_partial. Add explicit error message for failing to read abbrev. (read_debug_info): Likewise. --- dwz.c | 146 +++++++++++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 120 insertions(+), 26 deletions(-) diff --git a/dwz.c b/dwz.c index 6a4c96c..5d4b004 100644 --- a/dwz.c +++ b/dwz.c @@ -670,6 +670,28 @@ get_DW_AT_str (unsigned int at) return buf; } +/* Retrun a DW_UT_* name. */ +static const char * +get_DW_UT_str (unsigned int ut) +{ + const char *name; + static char buf[7 + 3 * sizeof (int)]; + switch (ut) + { + case DW_UT_compile: name = "DW_UT_compile"; break; + case DW_UT_type: name = "DW_UT_type"; break; + case DW_UT_partial: name = "DW_UT_partial"; break; + case DW_UT_skeleton: name = "DW_UT_partial"; break; + case DW_UT_split_compile: name = "DW_UT_split_compile"; break; + case DW_UT_split_type: name = "DW_UT_split_type"; break; + default: name = 0; break; + } + if (name) + return name; + sprintf (buf, "DW_UT_%u", ut); + return buf; +} + /* This must match the debug_sections array content below. */ enum debug_section_kind @@ -1332,8 +1354,8 @@ read_debug_line (DSO *dso, dw_cu_ref cu, uint32_t off) value = read_16 (ptr); if (value < 2 || value > 4) { - error (0, 0, "%s: DWARF version %d unhandled", dso->filename, - value); + error (0, 0, "%s: DWARF version %d in .debug_line unhandled", + dso->filename, value); return 1; } @@ -5572,24 +5594,41 @@ try_debug_info (DSO *dso) } cu_version = read_16 (ptr); - if (cu_version < 2 || cu_version > 4) + if (kind == DEBUG_TYPES && + (cu_version < 2 || cu_version > 4)) { - error (0, 0, "%s: DWARF version %d unhandled", dso->filename, - cu_version); + error (0, 0, "%s: DWARF version %d in .debug_types unhandled", + dso->filename, cu_version); goto fail; } - - value = read_32 (ptr); - if (value >= debug_sections[DEBUG_ABBREV].size) + else if (cu_version < 2 || cu_version > 5) { - if (debug_sections[DEBUG_ABBREV].data == NULL) - error (0, 0, "%s: .debug_abbrev not present", dso->filename); - else - error (0, 0, "%s: DWARF CU abbrev offset too large", - dso->filename); + error (0, 0, "%s: DWARF version %d in .debug_info unhandled", + dso->filename, cu_version); goto fail; } + if (cu_version == 5) + { + value = read_8 (ptr); + if (value != DW_UT_compile && value != DW_UT_partial) + error (0, 0, "%s: DWARF CU type %s unhandled", dso->filename, + get_DW_UT_str (value)); + } + else + { + value = read_32 (ptr); + if (value >= debug_sections[DEBUG_ABBREV].size) + { + if (debug_sections[DEBUG_ABBREV].data == NULL) + error (0, 0, "%s: .debug_abbrev not present", dso->filename); + else + error (0, 0, "%s: DWARF CU abbrev offset too large", + dso->filename); + goto fail; + } + } + if (ptr_size == 0) { ptr_size = read_8 (ptr); @@ -5607,6 +5646,20 @@ try_debug_info (DSO *dso) goto fail; } + if (cu_version == 5) + { + value = read_32 (ptr); + if (value >= debug_sections[DEBUG_ABBREV].size) + { + if (debug_sections[DEBUG_ABBREV].data == NULL) + error (0, 0, "%s: .debug_abbrev not present", dso->filename); + else + error (0, 0, "%s: DWARF CU abbrev offset too large", + dso->filename); + goto fail; + } + } + if (abbrev == NULL || value != last_abbrev_offset) { if (abbrev) @@ -5614,7 +5667,11 @@ try_debug_info (DSO *dso) abbrev = read_abbrev (dso, debug_sections[DEBUG_ABBREV].data + value); if (abbrev == NULL) - goto fail; + { + error (0, 0, "%s: Couldn't read abbrev at offset 0x%x", + dso->filename, value); + goto fail; + } } last_abbrev_offset = value; @@ -5800,24 +5857,42 @@ read_debug_info (DSO *dso, int kind, unsigned int *die_count) } cu_version = read_16 (ptr); - if (cu_version < 2 || cu_version > 4) + if (kind == DEBUG_TYPES && + (cu_version < 2 || cu_version > 4)) { - error (0, 0, "%s: DWARF version %d unhandled", dso->filename, - cu_version); + error (0, 0, "%s: DWARF version %d in .debug_types unhandled", + dso->filename, cu_version); goto fail; } - - value = read_32 (ptr); - if (value >= debug_sections[DEBUG_ABBREV].size) + else if (cu_version < 2 || cu_version > 5) { - if (debug_sections[DEBUG_ABBREV].data == NULL) - error (0, 0, "%s: .debug_abbrev not present", dso->filename); - else - error (0, 0, "%s: DWARF CU abbrev offset too large", - dso->filename); + error (0, 0, "%s: DWARF version %d in .debug_info unhandled", + dso->filename, cu_version); goto fail; } + if (cu_version == 5) + { + value = read_8 (ptr); + if (value != DW_UT_compile && value != DW_UT_partial) + error (0, 0, "%s: DWARF CU type %s unhandled", dso->filename, + get_DW_UT_str (value)); + + } + else + { + value = read_32 (ptr); + if (value >= debug_sections[DEBUG_ABBREV].size) + { + if (debug_sections[DEBUG_ABBREV].data == NULL) + error (0, 0, "%s: .debug_abbrev not present", dso->filename); + else + error (0, 0, "%s: DWARF CU abbrev offset too large", + dso->filename); + goto fail; + } + } + if (ptr_size == 0) { ptr_size = read_8 (ptr); @@ -5835,6 +5910,20 @@ read_debug_info (DSO *dso, int kind, unsigned int *die_count) goto fail; } + if (cu_version == 5) + { + value = read_32 (ptr); + if (value >= debug_sections[DEBUG_ABBREV].size) + { + if (debug_sections[DEBUG_ABBREV].data == NULL) + error (0, 0, "%s: .debug_abbrev not present", dso->filename); + else + error (0, 0, "%s: DWARF CU abbrev offset too large", + dso->filename); + goto fail; + } + } + if (unlikely (op_multifile)) { if (ptr == endcu) @@ -5914,7 +6003,12 @@ read_debug_info (DSO *dso, int kind, unsigned int *die_count) abbrev = read_abbrev (dso, debug_sections[DEBUG_ABBREV].data + value); if (abbrev == NULL) - goto fail; + { + error (0, 0, "%s: Couldn't read abbrev at offset 0x%x", + dso->filename, value); + + goto fail; + } } last_abbrev_offset = value; -- 2.18.4