From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from simark.ca by simark.ca with LMTP id wMKRJ4jDfGhHdSoAWB0awg (envelope-from ) for ; Sun, 20 Jul 2025 06:23:04 -0400 Authentication-Results: simark.ca; dkim=pass (1024-bit key; unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=ZDrej/me; dkim-atps=neutral Received: by simark.ca (Postfix, from userid 112) id 9BBB81E11C; Sun, 20 Jul 2025 06:23:04 -0400 (EDT) X-Spam-Checker-Version: SpamAssassin 4.0.1 (2024-03-25) on simark.ca X-Spam-Level: X-Spam-Status: No, score=-6.8 required=5.0 tests=ARC_SIGNED,ARC_VALID,BAYES_00, DKIMWL_WL_HIGH,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,MAILING_LIST_MULTI, RCVD_IN_DNSWL_MED,RCVD_IN_SBL_CSS,RCVD_IN_VALIDITY_CERTIFIED, RCVD_IN_VALIDITY_RPBL,RCVD_IN_VALIDITY_SAFE autolearn=ham autolearn_force=no version=4.0.1 Received: from server2.sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature ECDSA (prime256v1) server-digest SHA256) (No client certificate requested) by simark.ca (Postfix) with ESMTPS id 2CDAE1E102 for ; Sun, 20 Jul 2025 06:23:01 -0400 (EDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id AA1723858019 for ; Sun, 20 Jul 2025 10:23:00 +0000 (GMT) DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org AA1723858019 Authentication-Results: sourceware.org; dkim=pass (1024-bit key, unprotected) header.d=redhat.com header.i=@redhat.com header.a=rsa-sha256 header.s=mimecast20190719 header.b=ZDrej/me Received: from us-smtp-delivery-124.mimecast.com (us-smtp-delivery-124.mimecast.com [170.10.129.124]) by sourceware.org (Postfix) with ESMTP id 85AF33858C54 for ; Sun, 20 Jul 2025 10:21:02 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.4.2 sourceware.org 85AF33858C54 Authentication-Results: sourceware.org; dmarc=pass (p=quarantine dis=none) header.from=redhat.com Authentication-Results: sourceware.org; spf=pass smtp.mailfrom=redhat.com ARC-Filter: OpenARC Filter v1.0.0 sourceware.org 85AF33858C54 Authentication-Results: server2.sourceware.org; arc=none smtp.remote-ip=170.10.129.124 ARC-Seal: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1753006862; cv=none; b=pMmC5GFFflyBcMkj7DLCBUmKGVDFx0CokVmbq/sHBf9Mv1NlgpnYurkmzvMZOolh69zcLquB9GyR03ioJRVDUxUOtx2yjH5EJiv2SP2pP1R2cZWz4y9vmlFUWPj58kx7R6KyhsBDqC7RFItRJl7IHUbpHCONmW1FNjc0dQbBxik= ARC-Message-Signature: i=1; a=rsa-sha256; d=sourceware.org; s=key; t=1753006862; c=relaxed/simple; bh=EYPr1z4q/KotnkJqwJPVqnKAdIM8J0BgA/Vhio6AzF0=; h=DKIM-Signature:From:To:Subject:Date:Message-ID:MIME-Version; b=OaisdTxCjJIsaVS/vh1UJh6th406aGnV/YWbyJTFXfATxMdOWeWjuYX0B+G1Zj2CIvBaKZSMRUA4b/s6IMEkprfq/B+9U4lH+8WgtVvakIRDqtp3f4x9a0cSAzSZGdlE3C2YT2U2w2O+0KiweGLldFPkCyhfKOxGFlVfq5bORZc= ARC-Authentication-Results: i=1; server2.sourceware.org DKIM-Filter: OpenDKIM Filter v2.11.0 sourceware.org 85AF33858C54 DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=redhat.com; s=mimecast20190719; t=1753006862; h=from:from:reply-to:subject:subject:date:date:message-id:message-id: to:to:cc:cc:mime-version:mime-version:content-type:content-type: content-transfer-encoding:content-transfer-encoding: in-reply-to:in-reply-to:references:references; bh=81hbLXXK/bTMk8s8CH1f6uvTkFXEFtJZmFVL/F3XlEc=; b=ZDrej/mesFqw/hW35Ydw8z+sAhQBQloSIUY1+RpIUTSfYs1plo/OD4IPBn+0fHQYZhvCFt 4UIY1PDMav/IrzsZSk4s9hjpASxBpq4NKbxadIVM5Gd1Zm4dZ/RpogXb6jwCAEXcYWTkuw LFooH2Zucq2nywuIwi6MCQ2ooNh8uwI= Received: from mail-wm1-f69.google.com (mail-wm1-f69.google.com [209.85.128.69]) by relay.mimecast.com with ESMTP with STARTTLS (version=TLSv1.3, cipher=TLS_AES_256_GCM_SHA384) id us-mta-587-zmL3z93LPcmdEt-F9qmb9w-1; Sun, 20 Jul 2025 06:21:00 -0400 X-MC-Unique: zmL3z93LPcmdEt-F9qmb9w-1 X-Mimecast-MFC-AGG-ID: zmL3z93LPcmdEt-F9qmb9w_1753006859 Received: by mail-wm1-f69.google.com with SMTP id 5b1f17b1804b1-45639e6a320so14513015e9.3 for ; Sun, 20 Jul 2025 03:21:00 -0700 (PDT) X-Google-DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=1e100.net; s=20230601; t=1753006858; x=1753611658; h=content-transfer-encoding:mime-version:references:in-reply-to :message-id:date:subject:cc:to:from:x-gm-message-state:from:to:cc :subject:date:message-id:reply-to; bh=81hbLXXK/bTMk8s8CH1f6uvTkFXEFtJZmFVL/F3XlEc=; b=eJQ7Cr9FL1FxukFIMBp0dugkU+fAgJWbQmR80CAlXfQWqG0xjTOsw6vti5d1vaaUHu p3k7GovNVw9NhyE2YF/Qyb1LVn2ZtUq9VJAc6YnMCurUeS4lVEtm+EE3r/fDOob3I6fJ 0esz8V/ZVa88d8VKpg/s9/gesZ5kMDEo27cXifo6gioWJmwHyKd/tNi60HXXZtsaXaRT tZAyqefcFvf5bwJUdm8xHYfDgLhM3C0ni04uJkLXVbqG6lJ7N+3w2rwd/evo00Uf08v1 JuESKq/QkdCa/DV8/uFkqv7pg+7Eb0sUzN90BnuLq1Cl8cnQ5JDyxeSDZgEXpJ5uvmOu g8QA== X-Gm-Message-State: AOJu0YwgY6YHbyOGZhPSTpfW0sW26vOnwg6K2oolcwPDquJEs6DaflON Njdj/b3WqpBjG9HvaXBvlk4K/jFH4t5gZJabDKvYH0+AYCsMOLGx3CGNS+jtGmesJtgnNFny3CJ TqVqDNPTRpRm6fI0Oi8eKM0AnP+ETarMNGte6B0K2QVu/qenjjROuyEo9Sj4GkjaNnjEg7tFB/O AjmUInK3K5o0Cm8avcduK7/7IkjOCznabjfmscYKcMBE4W4fE= X-Gm-Gg: ASbGncs8NFhaMayKiIbDo5a/UraPyOfciI51MtHvvNKzMD6yXQvTIfcwNTZg1E++D2q dg/gYkE2Hot5lfLMwf7DlmpZs2Ss6e1WM+u4vB1MPHr0zVQCGbUq4paPbqBz8WfpnA5jcwNj4X3 rsbCvvC4lqkutdtkHOuNOEKKG5Z0e1J2eKB+oebTMVNuINmwUH36i67uwo7F9mWiX6O/BlXwu5V sD5lmzRwAKJ9D+Rm7rKpDe3uLsmvJGCjrLHAomow1+I9/ouMfcy2sPy5J5scKkXgHBwkSenSD23 bInpSOIjkk9fjAcTlYZuwoteHDpONiUrKASF+O/3fGP7HnO53rJCfBlgRJ9T5A== X-Received: by 2002:a05:600c:8b28:b0:456:1e5a:8879 with SMTP id 5b1f17b1804b1-4562e341199mr171970455e9.9.1753006858242; Sun, 20 Jul 2025 03:20:58 -0700 (PDT) X-Google-Smtp-Source: AGHT+IHhnihMVbDgdoyPc6DaC1ICgyjDmgK9WTf5DP1caM0FAHb/BW36/xMV3efFZ7sg1nW6KtqV7A== X-Received: by 2002:a05:600c:8b28:b0:456:1e5a:8879 with SMTP id 5b1f17b1804b1-4562e341199mr171970245e9.9.1753006857668; Sun, 20 Jul 2025 03:20:57 -0700 (PDT) Received: from localhost (92.40.185.56.threembb.co.uk. [92.40.185.56]) by smtp.gmail.com with ESMTPSA id ffacd0b85a97d-3b61ca5c632sm7244359f8f.80.2025.07.20.03.20.57 (version=TLS1_3 cipher=TLS_AES_256_GCM_SHA384 bits=256/256); Sun, 20 Jul 2025 03:20:57 -0700 (PDT) From: Andrew Burgess To: gdb-patches@sourceware.org Cc: Andrew Burgess Subject: [PATCH 3/7] gdb: split dwarf line table parsing in two Date: Sun, 20 Jul 2025 11:20:42 +0100 Message-ID: <9ba60bd4e8866eb78ce983508043ccfe8dbb6f14.1753006060.git.aburgess@redhat.com> X-Mailer: git-send-email 2.47.1 In-Reply-To: References: MIME-Version: 1.0 X-Mimecast-Spam-Score: 0 X-Mimecast-MFC-PROC-ID: CDfMDAu7mrJu0_PauYCcK6y5Iox9uayOo85BD6bkrjU_1753006859 X-Mimecast-Originator: redhat.com Content-Transfer-Encoding: 8bit content-type: text/plain; charset="US-ASCII"; x-default=true 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~public-inbox=simark.ca@sourceware.org A later commit in this series, that improves GDB's ability to debug optimised code, wants to use the line table information in order to "fix" inline blocks with a truncated address range. For the reasoning behind wanting to do that, please read ahead in the series. Assuming that we accept for now the need to use the line table information to adjust the block ranges, then why is this commit needed? GDB splits the line table data info different symtabs, adding end of sequence markers as we move between symtabs. This seems to work fine for GDB, but causes a problem for me in this case. What I will want to do is this: scan the line table and spot line table entries that corresponds to the end addresses of an inline block's address range. If the block meets certain requirements, then the end address of the block is adjusted to be that of the next line table entry. The way that GDB currently splits the line table entries between symtabs makes this harder. I will have the set of blocks end addresses which I know might be fixable, but to find the line table entry corresponding to that address requires searching through all the symtabs. Having found the entry for the end address, I then need to find the next line table entry. For some blocks this is easy, it's the next entry in the same symtab. But for other blocks the next entry might be in a different symtab, which requires yet another full search. I did try implementing this approach, but the number of full symtab searches is significant, and it had a significant impact on GDB's debug parsing performance. The impact was such that an operation that currently takes ~7seconds would take ~3minutes or more. Now I could possibly improve that 3 minutes figure by optimising the code some, but I think that would add unnecessary complexity. By deferring building the line table until after we have parsed the DIEs it becomes simple to spot when a line table entry corresponds to a block end address, and finding the next entry is always trivial, as, at this point, the next entry is just the next entry which we will process. With this approach I see no noticable impact on DWARF parsing performance. This patch is just the refactoring. There's no finding block end addresses and "fixing" being done here. This just sets things up for the later commits. There should be no user visible changes after this commit. --- gdb/dwarf2/read.c | 111 +++++++++++++++++++++++++--------------------- 1 file changed, 61 insertions(+), 50 deletions(-) diff --git a/gdb/dwarf2/read.c b/gdb/dwarf2/read.c index 02641588f96..46f87c097b4 100644 --- a/gdb/dwarf2/read.c +++ b/gdb/dwarf2/read.c @@ -787,9 +787,7 @@ static line_header_up dwarf_decode_line_header (sect_offset sect_off, struct dwarf2_cu *cu, const char *comp_dir); -static void dwarf_decode_lines (struct line_header *, - struct dwarf2_cu *, - unrelocated_addr, int decode_mapping); +static void dwarf_decode_lines (struct dwarf2_cu *cu, unrelocated_addr lowpc); static void dwarf2_start_subfile (dwarf2_cu *cu, const file_entry &fe, const line_header &lh); @@ -5866,29 +5864,55 @@ find_file_and_directory (struct die_info *die, struct dwarf2_cu *cu) return *cu->per_cu->fnd; } -/* Handle DW_AT_stmt_list for a compilation unit. - DIE is the DW_TAG_compile_unit die for CU. - COMP_DIR is the compilation directory. LOWPC is passed to - dwarf_decode_lines. See dwarf_decode_lines comments about it. */ +/* Ensure that every file_entry within the line_table of CU has a symtab + allocated for it. */ static void -handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu, - const file_and_directory &fnd, unrelocated_addr lowpc, - bool have_code) /* ARI: editCase function */ +create_symtabs_from_cu_line_table (struct dwarf2_cu *cu) { - dwarf2_per_objfile *per_objfile = cu->per_objfile; - struct attribute *attr; - hashval_t line_header_local_hash; - void **slot; - int decode_mapping; + /* Make sure a symtab is created for every file, even files + which contain only variables (i.e. no code with associated + line numbers). */ + buildsym_compunit *builder = cu->get_builder (); + struct compunit_symtab *cust = builder->get_compunit_symtab (); - gdb_assert (! cu->per_cu->is_debug_types); + struct line_header *lh = cu->line_header; + gdb_assert (lh != nullptr); - attr = dwarf2_attr (die, DW_AT_stmt_list, cu); + for (auto &fe : lh->file_names ()) + { + dwarf2_start_subfile (cu, fe, *lh); + subfile *sf = builder->get_current_subfile (); + + if (sf->symtab == nullptr) + sf->symtab = allocate_symtab (cust, sf->name.c_str (), + sf->name_for_id.c_str ()); + + fe.symtab = sf->symtab; + } +} + + +/* Handle DW_AT_stmt_list for a compilation unit. DIE is the + DW_TAG_compile_unit die for CU. FND is used to access the compilation + directory. This function will decode the line table header and create + symtab objects for the files referenced in the line table. The line + table itself though is not processed by this function. If there is no + line table, or there's a problem decoding the header, then CU will not + be updated. */ + +static void +decode_line_header_for_cu (struct die_info *die, struct dwarf2_cu *cu, + const file_and_directory &fnd) +{ + gdb_assert (!cu->per_cu->is_debug_types); + + struct attribute *attr = dwarf2_attr (die, DW_AT_stmt_list, cu); if (attr == NULL || !attr->form_is_unsigned ()) return; sect_offset line_offset = (sect_offset) attr->as_unsigned (); + dwarf2_per_objfile *per_objfile = cu->per_objfile; /* The line header hash table is only created if needed (it exists to prevent redundant reading of the line table for partial_units). @@ -5906,8 +5930,9 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu, xcalloc, xfree)); } + void **slot; line_header line_header_local (line_offset, cu->per_cu->is_dwz); - line_header_local_hash = line_header_hash (&line_header_local); + hashval_t line_header_local_hash = line_header_hash (&line_header_local); if (per_objfile->line_header_hash != NULL) { slot = htab_find_slot_with_hash (per_objfile->line_header_hash.get (), @@ -5960,12 +5985,8 @@ handle_DW_AT_stmt_list (struct die_info *die, struct dwarf2_cu *cu, then this is what we want as well. */ gdb_assert (die->tag != DW_TAG_partial_unit); } - decode_mapping = (die->tag != DW_TAG_partial_unit); - /* The have_code check is here because, if LOWPC and HIGHPC are both 0x0, - then there won't be any interesting code in the CU, but a check later on - (in lnp_state_machine::check_line_address) will fail to properly exclude - an entry that was removed via --gc-sections. */ - dwarf_decode_lines (cu->line_header, cu, lowpc, decode_mapping && have_code); + + create_symtabs_from_cu_line_table (cu); } /* Process DW_TAG_compile_unit or DW_TAG_partial_unit. */ @@ -6017,10 +6038,12 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu) scoped_restore restore_sym_cu = make_scoped_restore (&per_objfile->sym_cu, cu); - /* Decode line number information if present. We do this before - processing child DIEs, so that the line header table is available - for DW_AT_decl_file. */ - handle_DW_AT_stmt_list (die, cu, fnd, unrel_low, unrel_low != unrel_high); + /* Decode the line header if present. We do this before processing child + DIEs, so that information is available for DW_AT_decl_file. We defer + parsing the actual line table until after processing the child DIEs, + this allows us to fix up some of the inline function blocks as the + line table is read. */ + decode_line_header_for_cu (die, cu, fnd); /* Process all dies in compilation unit. */ for (die_info *child_die : die->children ()) @@ -6028,6 +6051,12 @@ read_file_scope (struct die_info *die, struct dwarf2_cu *cu) per_objfile->sym_cu = nullptr; + /* If we actually have code, then read the line table now. */ + if (unrel_low != unrel_high + && die->tag != DW_TAG_partial_unit + && cu->line_header != nullptr) + dwarf_decode_lines (cu, unrel_low); + /* Decode macro information, if present. Dwarf 2 macro information refers to information in the line number info statement program header, so we can only read it if we've read the header @@ -16552,29 +16581,11 @@ dwarf_decode_lines_1 (struct line_header *lh, struct dwarf2_cu *cu, table is read in. */ static void -dwarf_decode_lines (struct line_header *lh, struct dwarf2_cu *cu, - unrelocated_addr lowpc, int decode_mapping) +dwarf_decode_lines (struct dwarf2_cu *cu, unrelocated_addr lowpc) { - if (decode_mapping) - dwarf_decode_lines_1 (lh, cu, lowpc); + gdb_assert (cu->line_header != nullptr); - /* Make sure a symtab is created for every file, even files - which contain only variables (i.e. no code with associated - line numbers). */ - buildsym_compunit *builder = cu->get_builder (); - struct compunit_symtab *cust = builder->get_compunit_symtab (); - - for (auto &fe : lh->file_names ()) - { - dwarf2_start_subfile (cu, fe, *lh); - subfile *sf = builder->get_current_subfile (); - - if (sf->symtab == nullptr) - sf->symtab = allocate_symtab (cust, sf->name.c_str (), - sf->name_for_id.c_str ()); - - fe.symtab = sf->symtab; - } + dwarf_decode_lines_1 (cu->line_header, cu, lowpc); } /* Start a subfile for DWARF. FILENAME is the name of the file and @@ -16839,7 +16850,7 @@ new_symbol (struct die_info *die, struct type *type, struct dwarf2_cu *cu, if (file_cu->line_header == nullptr) { file_and_directory fnd (nullptr, nullptr); - handle_DW_AT_stmt_list (file_cu->dies, file_cu, fnd, {}, false); + decode_line_header_for_cu (file_cu->dies, file_cu, fnd); } if (file_cu->line_header != nullptr) -- 2.47.1