From patchwork Sat Oct 14 20:56:57 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 77782 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 29C723858C27 for ; Sat, 14 Oct 2023 20:58:26 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from omta40.uswest2.a.cloudfilter.net (omta40.uswest2.a.cloudfilter.net [35.89.44.39]) by sourceware.org (Postfix) with ESMTPS id 0464D3858C5F for ; Sat, 14 Oct 2023 20:58:07 +0000 (GMT) ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 0464D3858C5F Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=35.89.44.39 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1697317091; cv=none; b=YlhQSFEKHvdz4idf62OZudiDnKx6fKaNh9CV6cBW8PUmdTOltfdjCgnbTVXVAx2N8PEIPWIAm8/cSr6cF0shEuYx1oU0CLmHbOZa2e/m2h5Kow3qCcJv9EmzeWTVbCtTOGgyafA+TuyKbARq4PXDyUhB/Lo5tMcmbw6x+yb4J2g= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1697317091; c=relaxed/simple; bh=77e9dBKev9tcSQ8sAo+4+ONWV0Y3a6hLuAXVrDJx5rU=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=qgHkyISWDdKjb80R2PbvkAxjc+n3EeZLC2bzmvxWxn2oF47YjK75tTjBbLnpXREZvtLT41ObNykOEWeF8QV5+g74KlrywPHnYhS1G96xIpu/1cM+b1L6oXy/wfBLTEiqSLTOAFZByW+rAeJpvMecHR1Qnw2s3uPtocC4myfqzZQ= ARC-Authentication-Results: i=1; server2.sourceware.org DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 0464D3858C5F Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=tromey.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=tromey.com Received: from eig-obgw-6002a.ext.cloudfilter.net ([10.0.30.222]) by cmsmtp with ESMTP id rjQLq5HXKQUgRrli1qTlAP; Sat, 14 Oct 2023 20:58:05 +0000 Received: from box5379.bluehost.com ([162.241.216.53]) by cmsmtp with ESMTPS id rli0qkKyCasDqrli1qaAOO; Sat, 14 Oct 2023 20:58:05 +0000 X-Authority-Analysis: v=2.4 cv=CtCsz10D c=1 sm=1 tr=0 ts=652b00dd a=ApxJNpeYhEAb1aAlGBBbmA==:117 a=ApxJNpeYhEAb1aAlGBBbmA==:17 a=OWjo9vPv0XrRhIrVQ50Ab3nP57M=:19 a=dLZJa+xiwSxG16/P+YVxDGlgEgI=:19 a=bhdUkHdE2iEA:10 a=Qbun_eYptAEA:10 a=XjZJidyDlKjQaBls7d0A:9 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tromey.com; s=default; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=gFZg8/IjxeFAPl4XH6TOFeVVVwYKiyXExG37VtqVmVs=; b=KsTm3Esv5bCAgXrA5Laeyzr7O0 iImDpCd42+UMMKz+Zz/aJQl0jiGUynO/GPNyMXiKOdE7jiXBqAWydXBIRSBJWybO22urLCs+nPtBp Lu25veYUPVUQvLqNqMmA/2aO2; Received: from 71-211-130-31.hlrn.qwest.net ([71.211.130.31]:56746 helo=localhost.localdomain) by box5379.bluehost.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96.1) (envelope-from ) id 1qrli0-002r6O-1W; Sat, 14 Oct 2023 14:58:04 -0600 From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 1/2] Pre-read .debug_aranges section Date: Sat, 14 Oct 2023 14:56:57 -0600 Message-ID: <20231014205755.996771-2-tom@tromey.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231014205755.996771-1-tom@tromey.com> References: <20231014205755.996771-1-tom@tromey.com> MIME-Version: 1.0 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - box5379.bluehost.com X-AntiAbuse: Original Domain - sourceware.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - tromey.com X-BWhitelist: no X-Source-IP: 71.211.130.31 X-Source-L: No X-Exim-ID: 1qrli0-002r6O-1W X-Source: X-Source-Args: X-Source-Dir: X-Source-Sender: 71-211-130-31.hlrn.qwest.net (localhost.localdomain) [71.211.130.31]:56746 X-Source-Auth: tom+tromey.com X-Email-Count: 2 X-Org: HG=bhshared;ORG=bluehost; X-Source-Cap: ZWx5bnJvYmk7ZWx5bnJvYmk7Ym94NTM3OS5ibHVlaG9zdC5jb20= X-Local-Domain: yes X-CMAE-Envelope: MS4xfEXodODMdHUGZ5+dWX7MyjJUW7Cj+BUERZ6wVDpkgwiZTIlHF/Dzydp7lZcBwTN2ZF+e7U6heOj/gwwles0ltXEwe1M7HAXT3I7qt9PodudsjkrL8QOK FF5ywd2rxf8F4pm/yAP+ki/l4LjWgYF+2QDULs2dPmktK6iWjimfeLTxly9pX74FIlxtv+TeMgzYOCodmhz3vsRA/HPocxpEtGA= X-Spam-Status: No, score=-3024.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, GIT_PATCH_0, JMQ_SPF_NEUTRAL, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org While working on background DWARF reading, I found a race case that I tracked down to the handling of the .debug_aranges section. Currently the section data is only read in after the CUs have all been created. However, there's no real reason to do this -- it seems fine to read it a little earlier, when all the other necessary sections are read in. This patch makes this change, and updates the read_addrmap_from_aranges API to assert that the section is read in. This patch slightly changes the read_addrmap_from_aranges API as well, to reject an empty section. This seems better to me than what the current code does, which is try to read an empty section but then do no work. Regression tested on x86-64 Fedora 38. Reviewed-By: Guinevere Larsen --- gdb/dwarf2/read-debug-names.c | 1 + gdb/dwarf2/read.c | 11 ++++++----- 2 files changed, 7 insertions(+), 5 deletions(-) diff --git a/gdb/dwarf2/read-debug-names.c b/gdb/dwarf2/read-debug-names.c index 2e5067efb3d..89f5df6df90 100644 --- a/gdb/dwarf2/read-debug-names.c +++ b/gdb/dwarf2/read-debug-names.c @@ -166,6 +166,7 @@ create_addrmap_from_aranges (dwarf2_per_objfile *per_objfile, addrmap_mutable mutable_map; + section->read (per_objfile->objfile); if (read_addrmap_from_aranges (per_objfile, section, &mutable_map)) per_bfd->index_addrmap = new (&per_bfd->obstack) addrmap_fixed (&per_bfd->obstack, diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index d4aec19d31d..13ac83395eb 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -1586,6 +1586,7 @@ dwarf2_per_bfd::map_info_sections (struct objfile *objfile) ranges.read (objfile); rnglists.read (objfile); addr.read (objfile); + debug_aranges.read (objfile); for (auto §ion : types) section.read (objfile); @@ -1843,6 +1844,11 @@ read_addrmap_from_aranges (dwarf2_per_objfile *per_objfile, dwarf2_section_info *section, addrmap *mutable_map) { + /* Caller must ensure this is read in. */ + gdb_assert (section->readin); + if (section->empty ()) + return false; + struct objfile *objfile = per_objfile->objfile; bfd *abfd = objfile->obfd.get (); struct gdbarch *gdbarch = objfile->arch (); @@ -1870,13 +1876,8 @@ read_addrmap_from_aranges (dwarf2_per_objfile *per_objfile, } std::set debug_info_offset_seen; - - section->read (objfile); - const bfd_endian dwarf5_byte_order = gdbarch_byte_order (gdbarch); - const gdb_byte *addr = section->buffer; - while (addr < section->buffer + section->size) { const gdb_byte *const entry_addr = addr; From patchwork Sat Oct 14 20:56:58 2023 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Tom Tromey X-Patchwork-Id: 77783 Return-Path: X-Original-To: patchwork@sourceware.org Delivered-To: patchwork@sourceware.org Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 6E35E3857731 for ; Sat, 14 Oct 2023 20:58:42 +0000 (GMT) X-Original-To: gdb-patches@sourceware.org Delivered-To: gdb-patches@sourceware.org Received: from omta38.uswest2.a.cloudfilter.net (omta38.uswest2.a.cloudfilter.net [35.89.44.37]) by sourceware.org (Postfix) with ESMTPS id 097C63858C62 for ; Sat, 14 Oct 2023 20:58:07 +0000 (GMT) ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 097C63858C62 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=35.89.44.37 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1697317092; cv=none; b=Hc745h9Af83yqfV4O88V+MwQcD4cD+9iqDRQyOuo7NGkx1RK9wS16eVzX2VJdC/yKPHGp6xMPnKw4jA+UcEcth87uBUfOYa4plSwd/NkL2GOnXItGY43unjVeTqaUxlMMugZAmitg53i/T2uRfoLJAZdAkwIR5TfRE4FKlDUW/k= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1697317092; c=relaxed/simple; bh=LonZgrEGY28ns6bEsy5LawhdgXcHBo1OiGH5jIprPbE=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=jcgDq5MGGFn+Wkb1E7MHVgZg+m4fuDCTtdghEPhuomZfRm5vU1cAZQYEOi3iBfe6lfd9YOqEBxF/mKv0W40/HrZ+DS4x20wQiV5BoBTa9FfIEIQg8q/w12h00Idx21TdkNbhFns4RA0i6PyGVhEAxjWymP9WkoH/NxCW4B9/N9U= ARC-Authentication-Results: i=1; server2.sourceware.org DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 097C63858C62 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=tromey.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=tromey.com Received: from eig-obgw-5005a.ext.cloudfilter.net ([10.0.29.234]) by cmsmtp with ESMTP id rMwqqbcUaytxcrli1qniqr; Sat, 14 Oct 2023 20:58:06 +0000 Received: from box5379.bluehost.com ([162.241.216.53]) by cmsmtp with ESMTPS id rli0qAuEJsNVcrli1qibhP; Sat, 14 Oct 2023 20:58:05 +0000 X-Authority-Analysis: v=2.4 cv=H/vIfsUi c=1 sm=1 tr=0 ts=652b00dd a=ApxJNpeYhEAb1aAlGBBbmA==:117 a=ApxJNpeYhEAb1aAlGBBbmA==:17 a=OWjo9vPv0XrRhIrVQ50Ab3nP57M=:19 a=dLZJa+xiwSxG16/P+YVxDGlgEgI=:19 a=bhdUkHdE2iEA:10 a=Qbun_eYptAEA:10 a=mDV3o1hIAAAA:8 a=6kcINGlkKqLLZ71Fs_oA:9 a=_FVE-zBwftR9WsbkzFJk:22 DKIM-Signature: v=1; a=rsa-sha256; q=dns/txt; c=relaxed/relaxed; d=tromey.com; s=default; h=Content-Transfer-Encoding:MIME-Version:References:In-Reply-To: Message-ID:Date:Subject:Cc:To:From:Sender:Reply-To:Content-Type:Content-ID: Content-Description:Resent-Date:Resent-From:Resent-Sender:Resent-To:Resent-Cc :Resent-Message-ID:List-Id:List-Help:List-Unsubscribe:List-Subscribe: List-Post:List-Owner:List-Archive; bh=czqd3mqmTpyKH95J4wnhdFBW0Gda8Erd/CDU9T/D/wc=; b=Yon8a12yIaeaIy1yYi3tm9hSa0 0y5VfdxzBLMq6KA60Ij8znNEjeEIBC6vKm3Wt+w0gDHPYj8Ra1mClntLBIueUm+6PaIwDyWMwZST1 cyP2AR9KOoX/Pk7lopNRUq5KD; Received: from 71-211-130-31.hlrn.qwest.net ([71.211.130.31]:56746 helo=localhost.localdomain) by box5379.bluehost.com with esmtpsa (TLS1.2) tls TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384 (Exim 4.96.1) (envelope-from ) id 1qrli0-002r6O-23; Sat, 14 Oct 2023 14:58:04 -0600 From: Tom Tromey To: gdb-patches@sourceware.org Cc: Tom Tromey Subject: [PATCH 2/2] Move read_addrmap_from_aranges to new file Date: Sat, 14 Oct 2023 14:56:58 -0600 Message-ID: <20231014205755.996771-3-tom@tromey.com> X-Mailer: git-send-email 2.41.0 In-Reply-To: <20231014205755.996771-1-tom@tromey.com> References: <20231014205755.996771-1-tom@tromey.com> MIME-Version: 1.0 X-AntiAbuse: This header was added to track abuse, please include it with any abuse report X-AntiAbuse: Primary Hostname - box5379.bluehost.com X-AntiAbuse: Original Domain - sourceware.org X-AntiAbuse: Originator/Caller UID/GID - [47 12] / [47 12] X-AntiAbuse: Sender Address Domain - tromey.com X-BWhitelist: no X-Source-IP: 71.211.130.31 X-Source-L: No X-Exim-ID: 1qrli0-002r6O-23 X-Source: X-Source-Args: X-Source-Dir: X-Source-Sender: 71-211-130-31.hlrn.qwest.net (localhost.localdomain) [71.211.130.31]:56746 X-Source-Auth: tom+tromey.com X-Email-Count: 3 X-Org: HG=bhshared;ORG=bluehost; X-Source-Cap: ZWx5bnJvYmk7ZWx5bnJvYmk7Ym94NTM3OS5ibHVlaG9zdC5jb20= X-Local-Domain: yes X-CMAE-Envelope: MS4xfAKmiXwBVmCcYMpUnebxSVGuVfMV5AMKV8xKGKj+oM1mHMPImqh9QPBOzX+zwgUPYxDVOsMfB2hKqIOh/sZ842tbMNNKJzrBz5W0D/8k1wxaiP+XvKRW BADR/ZwuXS4gH8TXy5UASFqAlRRi3ZfesUxIyFl3kf5D0guAAJ4YYNtTHEsn1M1QwmCkJ5PAfQ8L9oTMEIyGD5sDB93TgbahoRg= X-Spam-Status: No, score=-3024.8 required=5.0 tests=BAYES_00, DKIM_SIGNED, DKIM_VALID, GIT_PATCH_0, JMQ_SPF_NEUTRAL, KAM_SHORT, RCVD_IN_DNSWL_LOW, RCVD_IN_MSPIKE_H2, SPF_HELO_NONE, SPF_PASS, TXREP autolearn=ham autolearn_force=no version=3.4.6 X-Spam-Checker-Version: SpamAssassin 3.4.6 (2021-04-09) on server2.sourceware.org X-BeenThere: gdb-patches@sourceware.org X-Mailman-Version: 2.1.30 Precedence: list List-Id: Gdb-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gdb-patches-bounces+patchwork=sourceware.org@sourceware.org In the interest of shrinking dwarf2/read.c a little more, this patch moves the code that deciphers .debug_aranges into a new file. --- gdb/Makefile.in | 2 + gdb/dwarf2/aranges.c | 200 ++++++++++++++++++++++++++++++++++ gdb/dwarf2/aranges.h | 35 ++++++ gdb/dwarf2/read-debug-names.c | 1 + gdb/dwarf2/read.c | 179 +----------------------------- gdb/dwarf2/read.h | 8 -- 6 files changed, 239 insertions(+), 186 deletions(-) create mode 100644 gdb/dwarf2/aranges.c create mode 100644 gdb/dwarf2/aranges.h diff --git a/gdb/Makefile.in b/gdb/Makefile.in index 9c0a0bff2cd..52b08692b52 100644 --- a/gdb/Makefile.in +++ b/gdb/Makefile.in @@ -1065,6 +1065,7 @@ COMMON_SFILES = \ dwarf2/abbrev.c \ dwarf2/abbrev-cache.c \ dwarf2/ada-imported.c \ + dwarf2/aranges.c \ dwarf2/attribute.c \ dwarf2/comp-unit-head.c \ dwarf2/cooked-index.c \ @@ -1321,6 +1322,7 @@ HFILES_NO_SRCDIR = \ disasm-flags.h \ disasm.h \ dummy-frame.h \ + dwarf2/aranges.h \ dwarf2/cooked-index.h \ dwarf2/cu.h \ dwarf2/frame-tailcall.h \ diff --git a/gdb/dwarf2/aranges.c b/gdb/dwarf2/aranges.c new file mode 100644 index 00000000000..3298d43e486 --- /dev/null +++ b/gdb/dwarf2/aranges.c @@ -0,0 +1,200 @@ +/* DWARF aranges handling + + Copyright (C) 1994-2023 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#include "defs.h" +#include "dwarf2/aranges.h" +#include "dwarf2/read.h" + +/* See aranges.h. */ + +bool +read_addrmap_from_aranges (dwarf2_per_objfile *per_objfile, + dwarf2_section_info *section, + addrmap *mutable_map) +{ + /* Caller must ensure this is read in. */ + gdb_assert (section->readin); + if (section->empty ()) + return false; + + struct objfile *objfile = per_objfile->objfile; + bfd *abfd = objfile->obfd.get (); + struct gdbarch *gdbarch = objfile->arch (); + dwarf2_per_bfd *per_bfd = per_objfile->per_bfd; + + std::unordered_map> + debug_info_offset_to_per_cu; + for (const auto &per_cu : per_bfd->all_units) + { + /* A TU will not need aranges, and skipping them here is an easy + way of ignoring .debug_types -- and possibly seeing a + duplicate section offset -- entirely. The same applies to + units coming from a dwz file. */ + if (per_cu->is_debug_types || per_cu->is_dwz) + continue; + + const auto insertpair + = debug_info_offset_to_per_cu.emplace (per_cu->sect_off, + per_cu.get ()); + + /* Assume no duplicate offsets in all_units. */ + gdb_assert (insertpair.second); + } + + std::set debug_info_offset_seen; + const bfd_endian dwarf5_byte_order = gdbarch_byte_order (gdbarch); + const gdb_byte *addr = section->buffer; + while (addr < section->buffer + section->size) + { + const gdb_byte *const entry_addr = addr; + unsigned int bytes_read; + + const LONGEST entry_length = read_initial_length (abfd, addr, + &bytes_read); + addr += bytes_read; + + const gdb_byte *const entry_end = addr + entry_length; + const bool dwarf5_is_dwarf64 = bytes_read != 4; + const uint8_t offset_size = dwarf5_is_dwarf64 ? 8 : 4; + if (addr + entry_length > section->buffer + section->size) + { + warning (_("Section .debug_aranges in %s entry at offset %s " + "length %s exceeds section length %s, " + "ignoring .debug_aranges."), + objfile_name (objfile), + plongest (entry_addr - section->buffer), + plongest (bytes_read + entry_length), + pulongest (section->size)); + return false; + } + + /* The version number. */ + const uint16_t version = read_2_bytes (abfd, addr); + addr += 2; + if (version != 2) + { + warning (_("Section .debug_aranges in %s entry at offset %s " + "has unsupported version %d, ignoring .debug_aranges."), + objfile_name (objfile), + plongest (entry_addr - section->buffer), version); + return false; + } + + const uint64_t debug_info_offset + = extract_unsigned_integer (addr, offset_size, dwarf5_byte_order); + addr += offset_size; + const auto per_cu_it + = debug_info_offset_to_per_cu.find (sect_offset (debug_info_offset)); + if (per_cu_it == debug_info_offset_to_per_cu.cend ()) + { + warning (_("Section .debug_aranges in %s entry at offset %s " + "debug_info_offset %s does not exists, " + "ignoring .debug_aranges."), + objfile_name (objfile), + plongest (entry_addr - section->buffer), + pulongest (debug_info_offset)); + return false; + } + const auto insertpair + = debug_info_offset_seen.insert (sect_offset (debug_info_offset)); + if (!insertpair.second) + { + warning (_("Section .debug_aranges in %s has duplicate " + "debug_info_offset %s, ignoring .debug_aranges."), + objfile_name (objfile), + sect_offset_str (sect_offset (debug_info_offset))); + return false; + } + dwarf2_per_cu_data *const per_cu = per_cu_it->second; + + const uint8_t address_size = *addr++; + if (address_size < 1 || address_size > 8) + { + warning (_("Section .debug_aranges in %s entry at offset %s " + "address_size %u is invalid, ignoring .debug_aranges."), + objfile_name (objfile), + plongest (entry_addr - section->buffer), address_size); + return false; + } + + const uint8_t segment_selector_size = *addr++; + if (segment_selector_size != 0) + { + warning (_("Section .debug_aranges in %s entry at offset %s " + "segment_selector_size %u is not supported, " + "ignoring .debug_aranges."), + objfile_name (objfile), + plongest (entry_addr - section->buffer), + segment_selector_size); + return false; + } + + /* Must pad to an alignment boundary that is twice the address + size. It is undocumented by the DWARF standard but GCC does + use it. However, not every compiler does this. We can see + whether it has happened by looking at the total length of the + contents of the aranges for this CU -- it if isn't a multiple + of twice the address size, then we skip any leftover + bytes. */ + addr += (entry_end - addr) % (2 * address_size); + + while (addr < entry_end) + { + if (addr + 2 * address_size > entry_end) + { + warning (_("Section .debug_aranges in %s entry at offset %s " + "address list is not properly terminated, " + "ignoring .debug_aranges."), + objfile_name (objfile), + plongest (entry_addr - section->buffer)); + return false; + } + ULONGEST start = extract_unsigned_integer (addr, address_size, + dwarf5_byte_order); + addr += address_size; + ULONGEST length = extract_unsigned_integer (addr, address_size, + dwarf5_byte_order); + addr += address_size; + if (start == 0 && length == 0) + { + /* This can happen on some targets with --gc-sections. + This pair of values is also used to mark the end of + the entries for a given CU, but we ignore it and + instead handle termination using the check at the top + of the loop. */ + continue; + } + if (start == 0 && !per_bfd->has_section_at_zero) + { + /* Symbol was eliminated due to a COMDAT group. */ + continue; + } + ULONGEST end = start + length; + start = (ULONGEST) per_objfile->adjust ((unrelocated_addr) start); + end = (ULONGEST) per_objfile->adjust ((unrelocated_addr) end); + mutable_map->set_empty (start, end - 1, per_cu); + } + + per_cu->addresses_seen = true; + } + + return true; +} diff --git a/gdb/dwarf2/aranges.h b/gdb/dwarf2/aranges.h new file mode 100644 index 00000000000..43e1cbd0930 --- /dev/null +++ b/gdb/dwarf2/aranges.h @@ -0,0 +1,35 @@ +/* DWARF aranges handling + + Copyright (C) 1994-2023 Free Software Foundation, Inc. + + This file is part of GDB. + + This program is free software; you can redistribute it and/or modify + it under the terms of the GNU General Public License as published by + the Free Software Foundation; either version 3 of the License, or + (at your option) any later version. + + This program is distributed in the hope that it will be useful, + but WITHOUT ANY WARRANTY; without even the implied warranty of + MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the + GNU General Public License for more details. + + You should have received a copy of the GNU General Public License + along with this program. If not, see . */ + +#ifndef GDB_DWARF2_ARANGES_H +#define GDB_DWARF2_ARANGES_H + +class dwarf2_per_objfile; +class dwarf2_section_info; +class addrmap; + +/* Read the address map data from DWARF-5 .debug_aranges, and use it + to populate given addrmap. Returns true on success, false on + failure. */ + +extern bool read_addrmap_from_aranges (dwarf2_per_objfile *per_objfile, + dwarf2_section_info *section, + addrmap *mutable_map); + +#endif /* GDB_DWARF2_ARANGES_H */ diff --git a/gdb/dwarf2/read-debug-names.c b/gdb/dwarf2/read-debug-names.c index 89f5df6df90..c1b62b38f93 100644 --- a/gdb/dwarf2/read-debug-names.c +++ b/gdb/dwarf2/read-debug-names.c @@ -19,6 +19,7 @@ #include "defs.h" #include "read-debug-names.h" +#include "dwarf2/aranges.h" #include "complaints.h" #include "cp-support.h" diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 13ac83395eb..1ca640df6be 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -31,6 +31,7 @@ #include "defs.h" #include "dwarf2/read.h" #include "dwarf2/abbrev.h" +#include "dwarf2/aranges.h" #include "dwarf2/attribute.h" #include "dwarf2/comp-unit-head.h" #include "dwarf2/cu.h" @@ -1837,184 +1838,6 @@ create_cu_from_index_list (dwarf2_per_bfd *per_bfd, return the_cu; } -/* See read.h. */ - -bool -read_addrmap_from_aranges (dwarf2_per_objfile *per_objfile, - dwarf2_section_info *section, - addrmap *mutable_map) -{ - /* Caller must ensure this is read in. */ - gdb_assert (section->readin); - if (section->empty ()) - return false; - - struct objfile *objfile = per_objfile->objfile; - bfd *abfd = objfile->obfd.get (); - struct gdbarch *gdbarch = objfile->arch (); - dwarf2_per_bfd *per_bfd = per_objfile->per_bfd; - - std::unordered_map> - debug_info_offset_to_per_cu; - for (const auto &per_cu : per_bfd->all_units) - { - /* A TU will not need aranges, and skipping them here is an easy - way of ignoring .debug_types -- and possibly seeing a - duplicate section offset -- entirely. The same applies to - units coming from a dwz file. */ - if (per_cu->is_debug_types || per_cu->is_dwz) - continue; - - const auto insertpair - = debug_info_offset_to_per_cu.emplace (per_cu->sect_off, - per_cu.get ()); - - /* Assume no duplicate offsets in all_units. */ - gdb_assert (insertpair.second); - } - - std::set debug_info_offset_seen; - const bfd_endian dwarf5_byte_order = gdbarch_byte_order (gdbarch); - const gdb_byte *addr = section->buffer; - while (addr < section->buffer + section->size) - { - const gdb_byte *const entry_addr = addr; - unsigned int bytes_read; - - const LONGEST entry_length = read_initial_length (abfd, addr, - &bytes_read); - addr += bytes_read; - - const gdb_byte *const entry_end = addr + entry_length; - const bool dwarf5_is_dwarf64 = bytes_read != 4; - const uint8_t offset_size = dwarf5_is_dwarf64 ? 8 : 4; - if (addr + entry_length > section->buffer + section->size) - { - warning (_("Section .debug_aranges in %s entry at offset %s " - "length %s exceeds section length %s, " - "ignoring .debug_aranges."), - objfile_name (objfile), - plongest (entry_addr - section->buffer), - plongest (bytes_read + entry_length), - pulongest (section->size)); - return false; - } - - /* The version number. */ - const uint16_t version = read_2_bytes (abfd, addr); - addr += 2; - if (version != 2) - { - warning (_("Section .debug_aranges in %s entry at offset %s " - "has unsupported version %d, ignoring .debug_aranges."), - objfile_name (objfile), - plongest (entry_addr - section->buffer), version); - return false; - } - - const uint64_t debug_info_offset - = extract_unsigned_integer (addr, offset_size, dwarf5_byte_order); - addr += offset_size; - const auto per_cu_it - = debug_info_offset_to_per_cu.find (sect_offset (debug_info_offset)); - if (per_cu_it == debug_info_offset_to_per_cu.cend ()) - { - warning (_("Section .debug_aranges in %s entry at offset %s " - "debug_info_offset %s does not exists, " - "ignoring .debug_aranges."), - objfile_name (objfile), - plongest (entry_addr - section->buffer), - pulongest (debug_info_offset)); - return false; - } - const auto insertpair - = debug_info_offset_seen.insert (sect_offset (debug_info_offset)); - if (!insertpair.second) - { - warning (_("Section .debug_aranges in %s has duplicate " - "debug_info_offset %s, ignoring .debug_aranges."), - objfile_name (objfile), - sect_offset_str (sect_offset (debug_info_offset))); - return false; - } - dwarf2_per_cu_data *const per_cu = per_cu_it->second; - - const uint8_t address_size = *addr++; - if (address_size < 1 || address_size > 8) - { - warning (_("Section .debug_aranges in %s entry at offset %s " - "address_size %u is invalid, ignoring .debug_aranges."), - objfile_name (objfile), - plongest (entry_addr - section->buffer), address_size); - return false; - } - - const uint8_t segment_selector_size = *addr++; - if (segment_selector_size != 0) - { - warning (_("Section .debug_aranges in %s entry at offset %s " - "segment_selector_size %u is not supported, " - "ignoring .debug_aranges."), - objfile_name (objfile), - plongest (entry_addr - section->buffer), - segment_selector_size); - return false; - } - - /* Must pad to an alignment boundary that is twice the address - size. It is undocumented by the DWARF standard but GCC does - use it. However, not every compiler does this. We can see - whether it has happened by looking at the total length of the - contents of the aranges for this CU -- it if isn't a multiple - of twice the address size, then we skip any leftover - bytes. */ - addr += (entry_end - addr) % (2 * address_size); - - while (addr < entry_end) - { - if (addr + 2 * address_size > entry_end) - { - warning (_("Section .debug_aranges in %s entry at offset %s " - "address list is not properly terminated, " - "ignoring .debug_aranges."), - objfile_name (objfile), - plongest (entry_addr - section->buffer)); - return false; - } - ULONGEST start = extract_unsigned_integer (addr, address_size, - dwarf5_byte_order); - addr += address_size; - ULONGEST length = extract_unsigned_integer (addr, address_size, - dwarf5_byte_order); - addr += address_size; - if (start == 0 && length == 0) - { - /* This can happen on some targets with --gc-sections. - This pair of values is also used to mark the end of - the entries for a given CU, but we ignore it and - instead handle termination using the check at the top - of the loop. */ - continue; - } - if (start == 0 && !per_bfd->has_section_at_zero) - { - /* Symbol was eliminated due to a COMDAT group. */ - continue; - } - ULONGEST end = start + length; - start = (ULONGEST) per_objfile->adjust ((unrelocated_addr) start); - end = (ULONGEST) per_objfile->adjust ((unrelocated_addr) end); - mutable_map->set_empty (start, end - 1, per_cu); - } - - per_cu->addresses_seen = true; - } - - return true; -} - /* die_reader_func for dw2_get_file_names. */ static void diff --git a/gdb/dwarf2/read.h b/gdb/dwarf2/read.h index 1d9432c5c11..2cf40a8c2cd 100644 --- a/gdb/dwarf2/read.h +++ b/gdb/dwarf2/read.h @@ -955,12 +955,4 @@ extern void finalize_all_units (dwarf2_per_bfd *per_bfd); extern htab_up create_quick_file_names_table (unsigned int nr_initial_entries); -/* Read the address map data from DWARF-5 .debug_aranges, and use it - to populate given addrmap. Returns true on success, false on - failure. */ - -extern bool read_addrmap_from_aranges (dwarf2_per_objfile *per_objfile, - dwarf2_section_info *section, - addrmap *mutable_map); - #endif /* DWARF2READ_H */