From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id eASDKBjCB2CaTgAAWB0awg (envelope-from ) for ; Wed, 20 Jan 2021 00:39:36 -0500 Received: by simark.ca (Postfix, from userid 112) id A157A1E939; Wed, 20 Jan 2021 00:39:36 -0500 (EST) X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on simark.ca X-Spam-Level: X-Spam-Status: No, score=0.2 required=5.0 tests=DKIM_SIGNED,DKIM_VALID, DKIM_VALID_AU,MAILING_LIST_MULTI,RDNS_NONE,URIBL_BLOCKED autolearn=no autolearn_force=no version=3.4.2 Received: from sourceware.org (unknown [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (2048 bits) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 0E3E21EF88 for ; Wed, 20 Jan 2021 00:39:35 -0500 (EST) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 7C504394848E; Wed, 20 Jan 2021 05:39:34 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 7C504394848E DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=sourceware.org; s=default; t=1611121174; bh=HvUObDWIJ71gjKJbbcntIoBSbNUuC/SXO6ScplbcKmQ=; h=To:Subject:Date:In-Reply-To:References:List-Id:List-Unsubscribe: List-Archive:List-Post:List-Help:List-Subscribe:From:Reply-To:Cc: From; b=VYczMQXIHaiHDqy41/OF1m+bDXrGVKSLEcKNto62C89IvNvqsuu4gts8FTQnlI1zi Lcq7IxVFGenephhP996ofqj8AkmEyycxMgvf2r0DFLgtdaeYwSzadTMtJuKApwefF+ jMxmWSghfQk58hnuAt/YbyGkCCL5k3QKBCYVADdg= Received: from barracuda.ebox.ca (barracuda.ebox.ca [96.127.255.19]) by sourceware.org (Postfix) with ESMTPS id 2D710383543C for ; Wed, 20 Jan 2021 05:39:29 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 2D710383543C X-ASG-Debug-ID: 1611121166-0c856e67e246f740001-fS2M51 Received: from smtp.ebox.ca (smtp.ebox.ca [96.127.255.82]) by barracuda.ebox.ca with ESMTP id EfpEyHS0jXv0fRXc (version=TLSv1 cipher=DHE-RSA-AES256-SHA bits=256 verify=NO); Wed, 20 Jan 2021 00:39:26 -0500 (EST) X-Barracuda-Envelope-From: simon.marchi@polymtl.ca X-Barracuda-RBL-Trusted-Forwarder: 96.127.255.82 Received: from simark.localdomain (192-222-157-6.qc.cable.ebox.net [192.222.157.6]) by smtp.ebox.ca (Postfix) with ESMTP id 635E8441D64; Wed, 20 Jan 2021 00:39:26 -0500 (EST) X-Barracuda-RBL-IP: 192.222.157.6 X-Barracuda-Effective-Source-IP: 192-222-157-6.qc.cable.ebox.net[192.222.157.6] X-Barracuda-Apparent-Source-IP: 192.222.157.6 To: gdb-patches@sourceware.org Subject: [PATCH 06/13] gdb/dwarf: read correct rnglist/loclist header in read_{rng, loc}list_index Date: Wed, 20 Jan 2021 00:39:18 -0500 X-ASG-Orig-Subj: [PATCH 06/13] gdb/dwarf: read correct rnglist/loclist header in read_{rng, loc}list_index Message-Id: <20210120053925.142862-7-simon.marchi@polymtl.ca> X-Mailer: git-send-email 2.30.0 In-Reply-To: <20210120053925.142862-1-simon.marchi@polymtl.ca> References: <20210120053925.142862-1-simon.marchi@polymtl.ca> MIME-Version: 1.0 Content-Transfer-Encoding: 8bit X-Barracuda-Connect: smtp.ebox.ca[96.127.255.82] X-Barracuda-Start-Time: 1611121166 X-Barracuda-Encrypted: DHE-RSA-AES256-SHA X-Barracuda-URL: https://96.127.255.19:443/cgi-mod/mark.cgi X-Virus-Scanned: by bsmtpd at ebox.ca X-Barracuda-Scan-Msg-Size: 6640 X-Barracuda-BRTS-Status: 1 X-Barracuda-Spam-Score: 0.50 X-Barracuda-Spam-Status: No, SCORE=0.50 using global scores of TAG_LEVEL=1000.0 QUARANTINE_LEVEL=1000.0 KILL_LEVEL=8.0 tests=BSF_RULE7568M X-Barracuda-Spam-Report: Code version 3.2, rules version 3.2.3.87375 Rule breakdown below pts rule name description ---- ---------------------- -------------------------------------------------- 0.50 BSF_RULE7568M Custom Rule 7568M X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , From: Simon Marchi via Gdb-patches Reply-To: Simon Marchi Cc: Simon Marchi Errors-To: gdb-patches-bounces@sourceware.org Sender: "Gdb-patches" From: Simon Marchi When loading the binary from PR 26813 in GDB, we get: DW_FORM_rnglistx index pointing outside of .debug_rnglists offset array [in module /home/simark/build/binutils-gdb/gdb/MagicPurse] ... and the symbols fail to load. In read_rnglist_index and read_loclist_index, we read the header (documented in sections 7.28 and 7.29 of DWARF 5) of the CU's contribution to the .debug_rnglists / .debug_loclists sections to validate that the index we want to read makes sense. However, we always read the header at the beginning of the section, rather than the header for the contribution from which we want to read the index. To illustrate, here's what the binary from PR 26813 contains. There are two compile units: 0x0000000c: DW_TAG_compile_unit 1 DW_AT_ranges [DW_FORM_rnglistx]: 0x0 DW_AT_rnglists_base [DW_FORM_sec_offset]: 0xC 0x00003ec9: DW_TAG_compile_unit 2 DW_AT_ranges [DW_FORM_rnglistx]: 0xB DW_AT_rnglists_base [DW_FORM_sec_offset]: 0x85 The layout of the .debug_rnglists is the following: [0x00, 0x0B]: header for CU 1's contribution [0x0C, 0x0F]: list of offsets for CU 1 (1 element) [0x10, 0x78]: range lists data for CU 1 [0x79, 0x84]: header for CU 2's contribution [0x85, 0xB4]: list of offsets for CU 2 (12 elements) [0xB5, 0xBD7]: range lists data for CU 2 The DW_AT_rnglists_base attrbute points to the beginning of the list of offsets for that CU, relative to the start of the .debug_rnglists section. That's right after the header for that contribution. When we try to read the DW_AT_ranges attribute for CU 2, read_rnglist_index reads the header for CU 1 instead of the one for CU 2. Since there's only one element in CU 1's offset list, it believes (wrongfully) that the index 0xB is out of range. Fix it by reading the header just before where DW_AT_rnglists_base points to. With this patch, I am able to load GDB built with clang-11 and -gdwarf-5 in itself, with and without -readnow. gdb/ChangeLog: PR gdb/26813 * dwarf2/read.c (read_loclists_rnglists_header): Add header_offset parameter and use it. (read_loclist_index): Read header of the current contribution, not the one at the beginning of the section. (read_rnglist_index): Likewise. Change-Id: Ie53ff8251af8c1556f0a83a31aa8572044b79e3d --- gdb/dwarf2/read.c | 44 ++++++++++++++++++++++++++++++++++++++------ 1 file changed, 38 insertions(+), 6 deletions(-) diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 4146694247ea..9701d422a338 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -20136,22 +20136,30 @@ partial_die_info::fixup (struct dwarf2_cu *cu) } /* Read the .debug_loclists or .debug_rnglists header (they are the same format) - contents from the given SECTION in the HEADER. */ + contents from the given SECTION in the HEADER. + + HEADER_OFFSET is the offset of the header in the section. */ static void read_loclists_rnglists_header (struct loclists_rnglists_header *header, - struct dwarf2_section_info *section) + struct dwarf2_section_info *section, + sect_offset header_offset) { unsigned int bytes_read; bfd *abfd = section->get_bfd_owner (); - const gdb_byte *info_ptr = section->buffer; + const gdb_byte *info_ptr = section->buffer + to_underlying (header_offset); + header->length = read_initial_length (abfd, info_ptr, &bytes_read); info_ptr += bytes_read; + header->version = read_2_bytes (abfd, info_ptr); info_ptr += 2; + header->addr_size = read_1_byte (abfd, info_ptr); info_ptr += 1; + header->segment_collector_size = read_1_byte (abfd, info_ptr); info_ptr += 1; + header->offset_entry_count = read_4_bytes (abfd, info_ptr); } @@ -20185,21 +20193,36 @@ read_loclist_index (struct dwarf2_cu *cu, ULONGEST loclist_index) dwarf2_per_objfile *per_objfile = cu->per_objfile; struct objfile *objfile = per_objfile->objfile; bfd *abfd = objfile->obfd; + ULONGEST loclist_header_size = + (cu->header.initial_length_size == 4 ? LOCLIST_HEADER_SIZE32 + : LOCLIST_HEADER_SIZE64); ULONGEST loclist_base = lookup_loclist_base (cu); /* Offset in .debug_loclists of the offset for LOCLIST_INDEX. */ ULONGEST start_offset = loclist_base + loclist_index * cu->header.offset_size; + /* Get loclists section. */ struct dwarf2_section_info *section = cu_debug_loc_section (cu); + /* Read the loclists section content. */ section->read (objfile); if (section->buffer == NULL) error (_("DW_FORM_loclistx used without .debug_loclists " "section [in module %s]"), objfile_name (objfile)); + /* DW_AT_loclists_base points after the .debug_loclists contribution header, + so if loclist_base is smaller than the header size, we have a problem. */ + if (loclist_base < loclist_header_size) + error (_("DW_AT_loclists_base is smaller than header size [in module %s]"), + objfile_name (objfile)); + + /* Read the header of the loclists contribution. */ struct loclists_rnglists_header header; - read_loclists_rnglists_header (&header, section); + read_loclists_rnglists_header (&header, section, + (sect_offset) (loclist_base - loclist_header_size)); + + /* Verify the loclist index is valid. */ if (loclist_index >= header.offset_entry_count) error (_("DW_FORM_loclistx pointing outside of " ".debug_loclists offset array [in module %s]"), @@ -20248,9 +20271,18 @@ read_rnglist_index (struct dwarf2_cu *cu, ULONGEST rnglist_index, "[in module %s]"), objfile_name (objfile)); - /* Verify the rnglist index is valid. */ + /* DW_AT_rnglists_base points after the .debug_rnglists contribution header, + so if rnglist_base is smaller than the header size, we have a problem. */ + if (rnglist_base < rnglist_header_size) + error (_("DW_AT_rnglists_base is smaller than header size [in module %s]"), + objfile_name (objfile)); + + /* Read the header of the rnglists contribution. */ struct loclists_rnglists_header header; - read_loclists_rnglists_header (&header, section); + read_loclists_rnglists_header (&header, section, + (sect_offset) (rnglist_base - rnglist_header_size)); + + /* Verify the rnglist index is valid. */ if (rnglist_index >= header.offset_entry_count) error (_("DW_FORM_rnglistx index pointing outside of " ".debug_rnglists offset array [in module %s]"), -- 2.30.0