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 660D73857C52 for ; Thu, 24 Sep 2020 16:26:21 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 660D73857C52 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 02C513000F11; Thu, 24 Sep 2020 18:26:20 +0200 (CEST) Received: by tarox.wildebeest.org (Postfix, from userid 1000) id F1174470867C; Thu, 24 Sep 2020 18:26:19 +0200 (CEST) From: Mark Wielaard To: dwz@sourceware.org Cc: Mark Wielaard Subject: [PATCH 3/4] Handle DW_FORM_line_strp by not moving DIE. Date: Thu, 24 Sep 2020 18:25:56 +0200 Message-Id: <20200924162557.15870-4-mark@klomp.org> X-Mailer: git-send-email 2.18.4 In-Reply-To: <20200924162557.15870-1-mark@klomp.org> References: <20200924162557.15870-1-mark@klomp.org> X-Spam-Status: No, score=-37.3 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: Thu, 24 Sep 2020 16:26:23 -0000 DW_FORM_line_strp points into a new string table .debug_line_str. There is no supplemental .debug_line_str, so DIEs having a line_strp form attribute cannot be moved. This isn't really a problem because normally DW_FORM_line_strp is only used for file paths used in top-level DW_AT_name and DW_AT_comp_dir, which wouldn't be moved anyway. When we add support for DWARF5 line tables we might revise the decision to keep the DW_FORM_line_strp as is since it might be advantaguous move the dir table and file table strings into the supplemental file .debug_str section. * dwz.c (read_abbrev): Accept DW_FORM_line_strp. (skip_attr_no_dw_form_indirect): Handle DW_FORM_line_strp. (get_AT_string): Return string from DEBUG_LINE_STR for DW_FORM_line_strp. (checksum_die): Make DIE CK_BAD for DW_FORM_line_strp to prevent moving. (die_eq_1): Handle DW_FORM_line_strp. (mark_refs): Likewise. (read_debug_info): Likewise. Don't note string. (build_abbrevs_for_die): Handle DW_FORM_line_strp. Keep form as is. (write_unit_die): Write out DW_FORM_line_strp data. (write_die): Likewise. --- dwz.c | 70 +++++++++++++++++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 66 insertions(+), 4 deletions(-) diff --git a/dwz.c b/dwz.c index 9719ee6..8f13298 100644 --- a/dwz.c +++ b/dwz.c @@ -1260,8 +1260,10 @@ read_abbrev (DSO *dso, unsigned char *ptr) nattr++; form = read_uleb128 (p); if (form == 2 - || (form > DW_FORM_flag_present && (form != DW_FORM_ref_sig8 - || form != DW_FORM_data16))) + || (form > DW_FORM_flag_present + && (form != DW_FORM_ref_sig8 + || form != DW_FORM_data16 + || form != DW_FORM_line_strp))) { error (0, 0, "%s: Unknown DWARF %s", dso->filename, get_DW_FORM_str (form)); @@ -1703,6 +1705,7 @@ skip_attr_no_dw_form_indirect (unsigned int cu_version, uint32_t form, case DW_FORM_data4: case DW_FORM_sec_offset: case DW_FORM_strp: + case DW_FORM_line_strp: ptr += 4; break; case DW_FORM_ref8: @@ -1869,6 +1872,14 @@ get_AT_string (dw_die_ref die, enum dwarf_attribute at) return NULL; return (char *) debug_sections[DEBUG_STR].data + strp; } + case DW_FORM_line_strp: + { + unsigned int line_strp = read_32 (ptr); + if (line_strp >= debug_sections[DEBUG_LINE_STR].size) + return NULL; + else + return (char *) debug_sections[DEBUG_LINE_STR].data + line_strp; + } default: return NULL; } @@ -3063,6 +3074,14 @@ checksum_die (DSO *dso, dw_cu_ref cu, dw_die_ref top_die, dw_die_ref die) } } break; + case DW_FORM_line_strp: + /* There is no .debug_line_str in the alt file, so we cannot + move this DIE unless we change the string reference. + This is not that bad because DW_FORM_line_strp is often + only used in the CU DIE for file name and comp_dir and we + don't move the CU DIE anyway. */ + die->die_ck_state = CK_BAD; + break; case DW_FORM_string: ptr = (unsigned char *) strchr ((char *)ptr, '\0') + 1; if (only_hash_name_p && t->attr[i].attr == DW_AT_name) @@ -3395,6 +3414,7 @@ checksum_ref_die (dw_cu_ref cu, dw_die_ref top_die, dw_die_ref die, case DW_FORM_data4: case DW_FORM_sec_offset: case DW_FORM_strp: + case DW_FORM_line_strp: ptr += 4; break; case DW_FORM_data8: @@ -4264,6 +4284,10 @@ die_eq_1 (dw_cu_ref cu1, dw_cu_ref cu2, ptr1 += 4; ptr2 += 4; break; + case DW_FORM_line_strp: + ptr1 += 4; + ptr2 += 4; + break; case DW_FORM_string: ptr1 = (unsigned char *) strchr ((char *)ptr1, '\0') + 1; ptr2 = (unsigned char *) strchr ((char *)ptr2, '\0') + 1; @@ -5303,6 +5327,7 @@ mark_refs (dw_cu_ref cu, dw_die_ref top_die, dw_die_ref die, int mode) case DW_FORM_data4: case DW_FORM_sec_offset: case DW_FORM_strp: + case DW_FORM_line_strp: ptr += 4; break; case DW_FORM_data8: @@ -6317,6 +6342,17 @@ read_debug_info (DSO *dso, int kind, unsigned int *die_count) else ptr += 4; break; + case DW_FORM_line_strp: + if (t->attr[i].attr == DW_AT_name + && (die->die_tag == DW_TAG_namespace + || die->die_tag == DW_TAG_module) + && !die->die_root + && (die->die_parent->die_root + || die->die_parent->die_named_namespace)) + die->die_named_namespace = 1; + /* Don't note strp, different string table. */ + ptr += 4; + break; case DW_FORM_string: ptr = (unsigned char *) strchr ((char *)ptr, '\0') + 1; if (t->attr[i].attr == DW_AT_name @@ -9983,6 +10019,11 @@ build_abbrevs_for_die (htab_t h, dw_cu_ref cu, dw_die_ref die, else ptr += 4; break; + case DW_FORM_line_strp: + /* Since we don't register the line_strp we cannot + change the form in the case of multifile. */ + ptr += 4; + break; case DW_FORM_string: ptr = (unsigned char *) strchr ((char *)ptr, '\0') + 1; break; @@ -10128,13 +10169,17 @@ build_abbrevs_for_die (htab_t h, dw_cu_ref cu, dw_die_ref die, { enum dwarf_form form; unsigned char *ptr = get_AT (origin, DW_AT_comp_dir, &form); - assert (ptr && (form == DW_FORM_string || form == DW_FORM_strp)); + assert (ptr && (form == DW_FORM_string + || form == DW_FORM_strp + || form == DW_FORM_line_strp)); if (form == DW_FORM_strp) { if (unlikely (op_multifile || fi_multifile)) form = note_strp_offset2 (read_32 (ptr)); die->die_size += 4; } + else if (form == DW_FORM_line_strp) + die->die_size += 4; else die->die_size += strlen (refcu->cu_comp_dir) + 1; @@ -10148,13 +10193,17 @@ build_abbrevs_for_die (htab_t h, dw_cu_ref cu, dw_die_ref die, { enum dwarf_form form; unsigned char *ptr = get_AT (origin, DW_AT_name, &form); - assert (ptr && (form == DW_FORM_string || form == DW_FORM_strp)); + assert (ptr && (form == DW_FORM_string + || form == DW_FORM_strp + || form == DW_FORM_line_strp)); if (form == DW_FORM_strp) { if (unlikely (op_multifile || fi_multifile)) form = note_strp_offset2 (read_32 (ptr)); die->die_size = 4; } + else if (form == DW_FORM_line_strp) + die->die_size += 4; else die->die_size = strlen ((char *) ptr) + 1; t->attr[0].attr = DW_AT_name; @@ -11254,6 +11303,11 @@ write_unit_die (unsigned char *ptr, dw_die_ref die, dw_die_ref origin) ptr += 4; } } + else if (form == DW_FORM_line_strp) + { + memcpy (ptr, p, 4); + ptr += 4; + } else { size_t len = strlen ((char *) p) + 1; @@ -11523,6 +11577,9 @@ write_die (unsigned char *ptr, dw_cu_ref cu, dw_die_ref die, } inptr += 4; break; + case DW_FORM_line_strp: + inptr += 4; + break; case DW_FORM_string: inptr = (unsigned char *) strchr ((char *)inptr, '\0') + 1; break; @@ -11703,6 +11760,11 @@ write_die (unsigned char *ptr, dw_cu_ref cu, dw_die_ref die, ptr += 4; } } + else if (form == DW_FORM_line_strp) + { + memcpy (ptr, p, 4); + ptr += 4; + } else { size_t len = strlen ((char *) p) + 1; -- 2.18.4