From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 92349 invoked by alias); 17 Feb 2020 11:59:03 -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 92337 invoked by uid 89); 17 Feb 2020 11:59:02 -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.1 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=FORM, su X-Spam-Status: No, score=-25.1 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: mx2.suse.de X-Virus-Scanned: by amavisd-new at test-mx.suse.de Date: Wed, 01 Jan 2020 00:00:00 -0000 From: Tom de Vries To: dwz@sourceware.org, jakub@redhat.com Subject: [committed] Handle DW_AT_language not encoded using DW_FORM_data{1,2} Message-ID: <20200217115851.GA2818@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: 2020-q1/txt/msg00074.txt Hi, Currently we handle DW_AT_language attributes encoded using DW_FORM_data1 and DW_FORM_data2. However, dwarf assembly test cases from the gdb testsuite typically use something like this: ... {DW_AT_language @DW_LANG_C} ... where the '@' prefix forces encoding using DW_FORM_sdata. The DW_FORM_sdata encoding will cause the DW_AT_language attribute to be ignored. Fix this by handling the DW_AT_language attribute encoded using any constant class encoding. Committed to trunk. Thanks, - Tom Handle DW_AT_language not encoded using DW_FORM_data{1,2} 2020-02-17 Tom de Vries * dwz.c (read_u16): New macro. (read_lang): New function. (read_debug_info): Read DW_AT_language encoded using DW_FORM_data{4,8} and DW_FORM_{s,u}data. --- dwz.c | 95 ++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++++--- 1 file changed, 92 insertions(+), 3 deletions(-) diff --git a/dwz.c b/dwz.c index 5748f6f..bfc320e 100644 --- a/dwz.c +++ b/dwz.c @@ -397,6 +397,63 @@ typedef struct } \ while (0) +/* Macro to parse a uint16_t value represented using form, return it and + update ptr to the end of the value at the same time. If the value doesn't + fit, assign true to error_p. */ +#define read_u16(ptr, form, error_p) \ + ({ \ + uint16_t ret = 0; \ + switch (form) \ + { \ + case DW_FORM_data1: \ + ret = read_8 (ptr); \ + break; \ + case DW_FORM_data2: \ + ret = read_16 (ptr); \ + break; \ + case DW_FORM_data4: \ + { \ + uint32_t res = read_32 (ptr); \ + ret = (uint16_t)res; \ + if ((uint32_t)ret != res) \ + error_p = true; \ + break; \ + } \ + case DW_FORM_data8: \ + { \ + uint64_t res = read_64 (ptr); \ + ret = (uint16_t)res; \ + if ((uint64_t)ret != res) \ + error_p = true; \ + break; \ + } \ + case DW_FORM_udata: \ + { \ + uint64_t res = read_uleb128 (ptr); \ + ret = (uint16_t)res; \ + if ((uint64_t)ret != res) \ + error_p = true; \ + break; \ + } \ + case DW_FORM_sdata: \ + { \ + union { \ + uint64_t u; \ + int64_t i; \ + } res; \ + res.u = read_sleb128 (ptr); \ + ret = (uint16_t)res.u; \ + if (res.i < 0 || (uint64_t)ret != res.u) \ + error_p = true; \ + break; \ + } \ + default: \ + error_p = true; \ + break; \ + } \ + ret; \ + }) + /* Pointer size in the debug info, in bytes. Only debug info with a single pointer size are handled. */ static int ptr_size; @@ -5592,6 +5649,23 @@ try_debug_info (DSO *dso) return ret; } +/* Read language attribute encoded using FORM from location PTR, return + pointer to location after the attribute. Assign the attribute value + to *LANG. */ +static unsigned char * +read_lang (unsigned char *ptr, enum dwarf_form form, + enum dwarf_source_language *lang) +{ + bool error_p = false; + *lang = read_u16 (ptr, form, error_p); + if (unlikely (error_p)) + { + *lang = 0; + error (0, 0, "Invalid DW_AT_language attribute, ignoring"); + } + return ptr; +} + /* First phase of the DWARF compression. Parse .debug_info section (for kind == DEBUG_INFO) or .debug_types section (for kind == DEBUG_TYPES) for each CU in it construct internal representation for the CU @@ -6007,19 +6081,34 @@ read_debug_info (DSO *dso, int kind, unsigned int *die_count) case DW_FORM_ref2: ptr += 2; break; - case DW_FORM_ref4: case DW_FORM_data4: + if (odr && die->die_tag == DW_TAG_compile_unit + && t->attr[i].attr == DW_AT_language) + read_lang (ptr, form, &cu->lang); + /* FALLTHRU */ + case DW_FORM_ref4: case DW_FORM_sec_offset: ptr += 4; break; - case DW_FORM_ref8: case DW_FORM_data8: + if (odr && die->die_tag == DW_TAG_compile_unit + && t->attr[i].attr == DW_AT_language) + read_lang (ptr, form, &cu->lang); + /* FALLTHRU */ + case DW_FORM_ref8: case DW_FORM_ref_sig8: ptr += 8; break; case DW_FORM_sdata: - case DW_FORM_ref_udata: case DW_FORM_udata: + if (odr && die->die_tag == DW_TAG_compile_unit + && t->attr[i].attr == DW_AT_language) + { + ptr = read_lang (ptr, form, &cu->lang); + break; + } + /* FALLTHRU */ + case DW_FORM_ref_udata: read_uleb128 (ptr); break; case DW_FORM_strp: